2011-09-27 06:30:58 +02:00
|
|
|
/*
|
|
|
|
|
* Tiny Code Interpreter for QEMU
|
|
|
|
|
*
|
2016-04-05 22:24:51 +02:00
|
|
|
* Copyright (c) 2009, 2011, 2016 Stefan Weil
|
2011-09-27 06:30:58 +02:00
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
2016-01-29 17:50:05 +00:00
|
|
|
#include "qemu/osdep.h"
|
2023-03-28 18:17:24 -07:00
|
|
|
#include "tcg/tcg.h"
|
2024-03-14 08:49:49 -10:00
|
|
|
#include "tcg/helper-info.h"
|
2021-07-27 11:10:22 -10:00
|
|
|
#include "tcg/tcg-ldst.h"
|
2024-04-19 07:37:00 +02:00
|
|
|
#include "disas/dis-asm.h"
|
2025-01-08 22:51:55 +01:00
|
|
|
#include "tcg-has.h"
|
2021-01-30 14:24:25 -08:00
|
|
|
#include <ffi.h>
|
2011-09-27 06:30:58 +02:00
|
|
|
|
2021-01-30 14:24:25 -08:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Enable TCI assertions only when debugging TCG (and without NDEBUG defined).
|
|
|
|
|
* Without assertions, the interpreter runs much faster.
|
|
|
|
|
*/
|
|
|
|
|
#if defined(CONFIG_DEBUG_TCG)
|
|
|
|
|
# define tci_assert(cond) assert(cond)
|
2011-09-27 06:30:58 +02:00
|
|
|
#else
|
2021-01-30 14:24:25 -08:00
|
|
|
# define tci_assert(cond) ((void)(cond))
|
2011-09-27 06:30:58 +02:00
|
|
|
#endif
|
|
|
|
|
|
2021-01-24 10:57:01 -10:00
|
|
|
__thread uintptr_t tci_tb_ptr;
|
|
|
|
|
|
2021-01-29 12:55:41 -10:00
|
|
|
/*
|
|
|
|
|
* Load sets of arguments all at once. The naming convention is:
|
|
|
|
|
* tci_args_<arguments>
|
|
|
|
|
* where arguments is a sequence of
|
|
|
|
|
*
|
2021-01-29 22:36:40 -10:00
|
|
|
* b = immediate (bit position)
|
2021-01-29 13:14:11 -10:00
|
|
|
* c = condition (TCGCond)
|
2021-01-29 21:49:24 -10:00
|
|
|
* i = immediate (uint32_t)
|
|
|
|
|
* I = immediate (tcg_target_ulong)
|
2021-01-29 21:18:45 -10:00
|
|
|
* l = label or pointer
|
2021-07-25 12:06:49 -10:00
|
|
|
* m = immediate (MemOpIdx)
|
2021-01-30 14:24:25 -08:00
|
|
|
* n = immediate (call return length)
|
2021-01-29 12:55:41 -10:00
|
|
|
* r = register
|
|
|
|
|
* s = signed ldst offset
|
|
|
|
|
*/
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_l(uint32_t insn, const void *tb_ptr, void **l0)
|
2021-01-30 13:23:02 -08:00
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
int diff = sextract32(insn, 12, 20);
|
|
|
|
|
*l0 = diff ? (void *)tb_ptr + diff : NULL;
|
2021-01-30 13:23:02 -08:00
|
|
|
}
|
|
|
|
|
|
2021-02-02 09:40:22 -10:00
|
|
|
static void tci_args_r(uint32_t insn, TCGReg *r0)
|
|
|
|
|
{
|
|
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_nl(uint32_t insn, const void *tb_ptr,
|
|
|
|
|
uint8_t *n0, void **l1)
|
2021-01-29 21:18:45 -10:00
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*n0 = extract32(insn, 8, 4);
|
|
|
|
|
*l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
|
2021-01-29 21:18:45 -10:00
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_rl(uint32_t insn, const void *tb_ptr,
|
|
|
|
|
TCGReg *r0, void **l1)
|
2021-01-30 14:24:25 -08:00
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*l1 = sextract32(insn, 12, 20) + (void *)tb_ptr;
|
2021-01-30 14:24:25 -08:00
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_rr(uint32_t insn, TCGReg *r0, TCGReg *r1)
|
2021-02-01 09:41:20 -10:00
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*r1 = extract32(insn, 12, 4);
|
2021-02-01 09:41:20 -10:00
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_ri(uint32_t insn, TCGReg *r0, tcg_target_ulong *i1)
|
2021-01-29 13:05:01 -10:00
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*i1 = sextract32(insn, 12, 20);
|
2021-01-29 13:05:01 -10:00
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_rrm(uint32_t insn, TCGReg *r0,
|
2021-07-25 12:06:49 -10:00
|
|
|
TCGReg *r1, MemOpIdx *m2)
|
2021-01-29 21:49:24 -10:00
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*r1 = extract32(insn, 12, 4);
|
2023-06-06 17:52:41 -07:00
|
|
|
*m2 = extract32(insn, 16, 16);
|
2021-01-29 21:49:24 -10:00
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_rrr(uint32_t insn, TCGReg *r0, TCGReg *r1, TCGReg *r2)
|
2021-01-29 21:49:24 -10:00
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*r1 = extract32(insn, 12, 4);
|
|
|
|
|
*r2 = extract32(insn, 16, 4);
|
2021-01-29 21:49:24 -10:00
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_rrs(uint32_t insn, TCGReg *r0, TCGReg *r1, int32_t *i2)
|
2021-01-29 22:52:12 -10:00
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*r1 = extract32(insn, 12, 4);
|
|
|
|
|
*i2 = sextract32(insn, 16, 16);
|
2021-01-29 22:52:12 -10:00
|
|
|
}
|
|
|
|
|
|
2021-02-02 16:48:48 -08:00
|
|
|
static void tci_args_rrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
|
|
|
|
|
uint8_t *i2, uint8_t *i3)
|
|
|
|
|
{
|
|
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*r1 = extract32(insn, 12, 4);
|
|
|
|
|
*i2 = extract32(insn, 16, 6);
|
|
|
|
|
*i3 = extract32(insn, 22, 6);
|
|
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_rrrc(uint32_t insn,
|
2021-01-29 13:14:11 -10:00
|
|
|
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGCond *c3)
|
|
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*r1 = extract32(insn, 12, 4);
|
|
|
|
|
*r2 = extract32(insn, 16, 4);
|
|
|
|
|
*c3 = extract32(insn, 20, 4);
|
2021-01-29 13:14:11 -10:00
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_rrrbb(uint32_t insn, TCGReg *r0, TCGReg *r1,
|
2021-01-29 22:36:40 -10:00
|
|
|
TCGReg *r2, uint8_t *i3, uint8_t *i4)
|
|
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*r1 = extract32(insn, 12, 4);
|
|
|
|
|
*r2 = extract32(insn, 16, 4);
|
|
|
|
|
*i3 = extract32(insn, 20, 6);
|
|
|
|
|
*i4 = extract32(insn, 26, 6);
|
2021-01-29 22:36:40 -10:00
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_rrrr(uint32_t insn,
|
2021-01-29 22:18:37 -10:00
|
|
|
TCGReg *r0, TCGReg *r1, TCGReg *r2, TCGReg *r3)
|
|
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*r1 = extract32(insn, 12, 4);
|
|
|
|
|
*r2 = extract32(insn, 16, 4);
|
|
|
|
|
*r3 = extract32(insn, 20, 4);
|
2021-01-29 22:18:37 -10:00
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
static void tci_args_rrrrrc(uint32_t insn, TCGReg *r0, TCGReg *r1,
|
2021-01-29 21:30:04 -10:00
|
|
|
TCGReg *r2, TCGReg *r3, TCGReg *r4, TCGCond *c5)
|
|
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
*r0 = extract32(insn, 8, 4);
|
|
|
|
|
*r1 = extract32(insn, 12, 4);
|
|
|
|
|
*r2 = extract32(insn, 16, 4);
|
|
|
|
|
*r3 = extract32(insn, 20, 4);
|
|
|
|
|
*r4 = extract32(insn, 24, 4);
|
|
|
|
|
*c5 = extract32(insn, 28, 4);
|
2021-01-29 21:30:04 -10:00
|
|
|
}
|
2021-01-29 22:16:05 -10:00
|
|
|
|
2011-09-27 06:30:58 +02:00
|
|
|
static bool tci_compare32(uint32_t u0, uint32_t u1, TCGCond condition)
|
|
|
|
|
{
|
|
|
|
|
bool result = false;
|
|
|
|
|
int32_t i0 = u0;
|
|
|
|
|
int32_t i1 = u1;
|
|
|
|
|
switch (condition) {
|
|
|
|
|
case TCG_COND_EQ:
|
|
|
|
|
result = (u0 == u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_NE:
|
|
|
|
|
result = (u0 != u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_LT:
|
|
|
|
|
result = (i0 < i1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_GE:
|
|
|
|
|
result = (i0 >= i1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_LE:
|
|
|
|
|
result = (i0 <= i1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_GT:
|
|
|
|
|
result = (i0 > i1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_LTU:
|
|
|
|
|
result = (u0 < u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_GEU:
|
|
|
|
|
result = (u0 >= u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_LEU:
|
|
|
|
|
result = (u0 <= u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_GTU:
|
|
|
|
|
result = (u0 > u1);
|
|
|
|
|
break;
|
2023-10-24 22:52:26 -07:00
|
|
|
case TCG_COND_TSTEQ:
|
|
|
|
|
result = (u0 & u1) == 0;
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_TSTNE:
|
|
|
|
|
result = (u0 & u1) != 0;
|
|
|
|
|
break;
|
2011-09-27 06:30:58 +02:00
|
|
|
default:
|
2021-01-27 20:11:11 -10:00
|
|
|
g_assert_not_reached();
|
2011-09-27 06:30:58 +02:00
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
|
|
|
|
|
{
|
|
|
|
|
bool result = false;
|
|
|
|
|
int64_t i0 = u0;
|
|
|
|
|
int64_t i1 = u1;
|
|
|
|
|
switch (condition) {
|
|
|
|
|
case TCG_COND_EQ:
|
|
|
|
|
result = (u0 == u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_NE:
|
|
|
|
|
result = (u0 != u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_LT:
|
|
|
|
|
result = (i0 < i1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_GE:
|
|
|
|
|
result = (i0 >= i1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_LE:
|
|
|
|
|
result = (i0 <= i1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_GT:
|
|
|
|
|
result = (i0 > i1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_LTU:
|
|
|
|
|
result = (u0 < u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_GEU:
|
|
|
|
|
result = (u0 >= u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_LEU:
|
|
|
|
|
result = (u0 <= u1);
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_GTU:
|
|
|
|
|
result = (u0 > u1);
|
|
|
|
|
break;
|
2023-10-24 22:52:26 -07:00
|
|
|
case TCG_COND_TSTEQ:
|
|
|
|
|
result = (u0 & u1) == 0;
|
|
|
|
|
break;
|
|
|
|
|
case TCG_COND_TSTNE:
|
|
|
|
|
result = (u0 & u1) != 0;
|
|
|
|
|
break;
|
2011-09-27 06:30:58 +02:00
|
|
|
default:
|
2021-01-27 20:11:11 -10:00
|
|
|
g_assert_not_reached();
|
2011-09-27 06:30:58 +02:00
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-20 07:48:09 -07:00
|
|
|
static uint64_t tci_qemu_ld(CPUArchState *env, uint64_t taddr,
|
2021-07-25 12:06:49 -10:00
|
|
|
MemOpIdx oi, const void *tb_ptr)
|
2021-05-27 12:21:59 -07:00
|
|
|
{
|
2021-08-03 14:56:51 -10:00
|
|
|
MemOp mop = get_memop(oi);
|
2021-05-27 12:37:57 -07:00
|
|
|
uintptr_t ra = (uintptr_t)tb_ptr;
|
|
|
|
|
|
2022-11-01 12:51:04 +11:00
|
|
|
switch (mop & MO_SSIZE) {
|
2021-05-27 12:37:57 -07:00
|
|
|
case MO_UB:
|
2022-11-01 12:51:04 +11:00
|
|
|
return helper_ldub_mmu(env, taddr, oi, ra);
|
2021-05-27 12:37:57 -07:00
|
|
|
case MO_SB:
|
2022-11-01 12:51:04 +11:00
|
|
|
return helper_ldsb_mmu(env, taddr, oi, ra);
|
|
|
|
|
case MO_UW:
|
|
|
|
|
return helper_lduw_mmu(env, taddr, oi, ra);
|
|
|
|
|
case MO_SW:
|
|
|
|
|
return helper_ldsw_mmu(env, taddr, oi, ra);
|
|
|
|
|
case MO_UL:
|
|
|
|
|
return helper_ldul_mmu(env, taddr, oi, ra);
|
|
|
|
|
case MO_SL:
|
|
|
|
|
return helper_ldsl_mmu(env, taddr, oi, ra);
|
|
|
|
|
case MO_UQ:
|
|
|
|
|
return helper_ldq_mmu(env, taddr, oi, ra);
|
2021-05-27 12:37:57 -07:00
|
|
|
default:
|
|
|
|
|
g_assert_not_reached();
|
|
|
|
|
}
|
2021-05-27 12:21:59 -07:00
|
|
|
}
|
|
|
|
|
|
2023-03-20 07:48:09 -07:00
|
|
|
static void tci_qemu_st(CPUArchState *env, uint64_t taddr, uint64_t val,
|
2021-07-25 12:06:49 -10:00
|
|
|
MemOpIdx oi, const void *tb_ptr)
|
2021-05-27 12:21:59 -07:00
|
|
|
{
|
2021-08-03 14:56:51 -10:00
|
|
|
MemOp mop = get_memop(oi);
|
2021-05-27 12:37:57 -07:00
|
|
|
uintptr_t ra = (uintptr_t)tb_ptr;
|
|
|
|
|
|
2022-11-01 12:51:04 +11:00
|
|
|
switch (mop & MO_SIZE) {
|
2021-05-27 12:37:57 -07:00
|
|
|
case MO_UB:
|
2022-11-01 12:51:04 +11:00
|
|
|
helper_stb_mmu(env, taddr, val, oi, ra);
|
2021-05-27 12:37:57 -07:00
|
|
|
break;
|
2022-11-01 12:51:04 +11:00
|
|
|
case MO_UW:
|
|
|
|
|
helper_stw_mmu(env, taddr, val, oi, ra);
|
2021-05-27 12:37:57 -07:00
|
|
|
break;
|
2022-11-01 12:51:04 +11:00
|
|
|
case MO_UL:
|
|
|
|
|
helper_stl_mmu(env, taddr, val, oi, ra);
|
2021-05-27 12:37:57 -07:00
|
|
|
break;
|
2022-11-01 12:51:04 +11:00
|
|
|
case MO_UQ:
|
|
|
|
|
helper_stq_mmu(env, taddr, val, oi, ra);
|
2021-05-27 12:37:57 -07:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_assert_not_reached();
|
|
|
|
|
}
|
2021-05-27 12:21:59 -07:00
|
|
|
}
|
|
|
|
|
|
2011-09-27 06:30:58 +02:00
|
|
|
/* Interpret pseudo code in tb. */
|
cfi: Initial support for cfi-icall in QEMU
LLVM/Clang, supports runtime checks for forward-edge Control-Flow
Integrity (CFI).
CFI on indirect function calls (cfi-icall) ensures that, in indirect
function calls, the function called is of the right signature for the
pointer type defined at compile time.
For this check to work, the code must always respect the function
signature when using function pointer, the function must be defined
at compile time, and be compiled with link-time optimization.
This rules out, for example, shared libraries that are dynamically loaded
(given that functions are not known at compile time), and code that is
dynamically generated at run-time.
This patch:
1) Introduces the CONFIG_CFI flag to support cfi in QEMU
2) Introduces a decorator to allow the definition of "sensitive"
functions, where a non-instrumented function may be called at runtime
through a pointer. The decorator will take care of disabling cfi-icall
checks on such functions, when cfi is enabled.
3) Marks functions currently in QEMU that exhibit such behavior,
in particular:
- The function in TCG that calls pre-compiled TBs
- The function in TCI that interprets instructions
- Functions in the plugin infrastructures that jump to callbacks
- Functions in util that directly call a signal handler
Signed-off-by: Daniele Buono <dbuono@linux.vnet.ibm.com>
Acked-by: Alex Bennée <alex.bennee@linaro.org
Message-Id: <20201204230615.2392-3-dbuono@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2020-12-04 18:06:12 -05:00
|
|
|
/*
|
|
|
|
|
* Disable CFI checks.
|
|
|
|
|
* One possible operation in the pseudo code is a call to binary code.
|
|
|
|
|
* Therefore, disable CFI checks in the interpreter function
|
|
|
|
|
*/
|
2020-10-28 12:05:44 -07:00
|
|
|
uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
|
|
|
|
const void *v_tb_ptr)
|
2011-09-27 06:30:58 +02:00
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
const uint32_t *tb_ptr = v_tb_ptr;
|
2017-07-13 17:10:31 -04:00
|
|
|
tcg_target_ulong regs[TCG_TARGET_NB_REGS];
|
2021-01-30 14:24:25 -08:00
|
|
|
uint64_t stack[(TCG_STATIC_CALL_ARGS_SIZE + TCG_STATIC_FRAME_SIZE)
|
|
|
|
|
/ sizeof(uint64_t)];
|
2025-01-20 19:46:04 -08:00
|
|
|
bool carry = false;
|
2011-09-27 06:30:58 +02:00
|
|
|
|
2017-07-13 17:10:31 -04:00
|
|
|
regs[TCG_AREG0] = (tcg_target_ulong)env;
|
2021-01-30 14:24:25 -08:00
|
|
|
regs[TCG_REG_CALL_STACK] = (uintptr_t)stack;
|
2016-04-05 22:24:51 +02:00
|
|
|
tci_assert(tb_ptr);
|
2011-09-27 06:30:58 +02:00
|
|
|
|
|
|
|
|
for (;;) {
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
uint32_t insn;
|
|
|
|
|
TCGOpcode opc;
|
2025-01-20 19:46:04 -08:00
|
|
|
TCGReg r0, r1, r2, r3, r4;
|
2011-09-27 06:30:58 +02:00
|
|
|
tcg_target_ulong t1;
|
|
|
|
|
TCGCond condition;
|
2021-01-29 22:36:40 -10:00
|
|
|
uint8_t pos, len;
|
2011-09-27 06:30:58 +02:00
|
|
|
uint32_t tmp32;
|
2026-01-07 12:52:50 +11:00
|
|
|
uint64_t taddr;
|
2021-07-25 12:06:49 -10:00
|
|
|
MemOpIdx oi;
|
2021-01-29 12:55:41 -10:00
|
|
|
int32_t ofs;
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
void *ptr;
|
2011-09-27 06:30:58 +02:00
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
insn = *tb_ptr++;
|
|
|
|
|
opc = extract32(insn, 0, 8);
|
2011-09-27 06:30:58 +02:00
|
|
|
|
|
|
|
|
switch (opc) {
|
|
|
|
|
case INDEX_op_call:
|
2022-10-21 10:47:54 +10:00
|
|
|
{
|
|
|
|
|
void *call_slots[MAX_CALL_IARGS];
|
|
|
|
|
ffi_cif *cif;
|
|
|
|
|
void *func;
|
|
|
|
|
unsigned i, s, n;
|
|
|
|
|
|
|
|
|
|
tci_args_nl(insn, tb_ptr, &len, &ptr);
|
|
|
|
|
func = ((void **)ptr)[0];
|
|
|
|
|
cif = ((void **)ptr)[1];
|
|
|
|
|
|
|
|
|
|
n = cif->nargs;
|
|
|
|
|
for (i = s = 0; i < n; ++i) {
|
|
|
|
|
ffi_type *t = cif->arg_types[i];
|
|
|
|
|
call_slots[i] = &stack[s];
|
|
|
|
|
s += DIV_ROUND_UP(t->size, 8);
|
2021-01-30 14:24:25 -08:00
|
|
|
}
|
|
|
|
|
|
2022-10-21 10:47:54 +10:00
|
|
|
/* Helper functions may need to access the "return address" */
|
|
|
|
|
tci_tb_ptr = (uintptr_t)tb_ptr;
|
|
|
|
|
ffi_call(cif, func, stack, call_slots);
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
}
|
2021-01-30 14:24:25 -08:00
|
|
|
|
|
|
|
|
switch (len) {
|
|
|
|
|
case 0: /* void */
|
|
|
|
|
break;
|
|
|
|
|
case 1: /* uint32_t */
|
|
|
|
|
/*
|
2022-10-21 10:34:21 +10:00
|
|
|
* The result winds up "left-aligned" in the stack[0] slot.
|
2021-01-30 14:24:25 -08:00
|
|
|
* Note that libffi has an odd special case in that it will
|
|
|
|
|
* always widen an integral result to ffi_arg.
|
|
|
|
|
*/
|
2022-10-21 10:34:21 +10:00
|
|
|
if (sizeof(ffi_arg) == 8) {
|
|
|
|
|
regs[TCG_REG_R0] = (uint32_t)stack[0];
|
|
|
|
|
} else {
|
2021-01-30 14:24:25 -08:00
|
|
|
regs[TCG_REG_R0] = *(uint32_t *)stack;
|
|
|
|
|
}
|
2022-10-21 10:34:21 +10:00
|
|
|
break;
|
2021-01-30 14:24:25 -08:00
|
|
|
case 2: /* uint64_t */
|
2022-10-21 10:34:21 +10:00
|
|
|
memcpy(®s[TCG_REG_R0], stack, 8);
|
2021-01-30 14:24:25 -08:00
|
|
|
break;
|
2022-10-21 10:47:54 +10:00
|
|
|
case 3: /* Int128 */
|
|
|
|
|
memcpy(®s[TCG_REG_R0], stack, 16);
|
|
|
|
|
break;
|
2021-01-30 14:24:25 -08:00
|
|
|
default:
|
|
|
|
|
g_assert_not_reached();
|
|
|
|
|
}
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2021-01-30 14:24:25 -08:00
|
|
|
|
2011-09-27 06:30:58 +02:00
|
|
|
case INDEX_op_br:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_l(insn, tb_ptr, &ptr);
|
2021-01-29 21:18:45 -10:00
|
|
|
tb_ptr = ptr;
|
2011-09-27 06:30:58 +02:00
|
|
|
continue;
|
2025-01-10 09:26:44 -08:00
|
|
|
case INDEX_op_setcond:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
|
2021-01-29 13:14:11 -10:00
|
|
|
regs[r0] = tci_compare64(regs[r1], regs[r2], condition);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-10 13:41:25 -08:00
|
|
|
case INDEX_op_movcond:
|
2021-02-02 16:15:45 -08:00
|
|
|
tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
|
|
|
|
|
tmp32 = tci_compare64(regs[r1], regs[r2], condition);
|
|
|
|
|
regs[r0] = regs[tmp32 ? r3 : r4];
|
|
|
|
|
break;
|
2024-12-28 15:58:24 -08:00
|
|
|
case INDEX_op_mov:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rr(insn, &r0, &r1);
|
2021-01-29 13:05:01 -10:00
|
|
|
regs[r0] = regs[r1];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
case INDEX_op_tci_movi:
|
|
|
|
|
tci_args_ri(insn, &r0, &t1);
|
2021-01-29 21:49:24 -10:00
|
|
|
regs[r0] = t1;
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
case INDEX_op_tci_movl:
|
|
|
|
|
tci_args_rl(insn, tb_ptr, &r0, &ptr);
|
|
|
|
|
regs[r0] = *(tcg_target_ulong *)ptr;
|
|
|
|
|
break;
|
2025-01-20 19:46:04 -08:00
|
|
|
case INDEX_op_tci_setcarry:
|
|
|
|
|
carry = true;
|
|
|
|
|
break;
|
2011-09-27 06:30:58 +02:00
|
|
|
|
|
|
|
|
/* Load/store operations (32 bit). */
|
|
|
|
|
|
2025-01-21 21:47:16 -08:00
|
|
|
case INDEX_op_ld8u:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
|
|
|
|
regs[r0] = *(uint8_t *)ptr;
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-21 21:47:16 -08:00
|
|
|
case INDEX_op_ld8s:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
|
|
|
|
regs[r0] = *(int8_t *)ptr;
|
2019-04-10 21:48:38 +02:00
|
|
|
break;
|
2025-01-21 21:47:16 -08:00
|
|
|
case INDEX_op_ld16u:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
|
|
|
|
regs[r0] = *(uint16_t *)ptr;
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-21 21:47:16 -08:00
|
|
|
case INDEX_op_ld16s:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
|
|
|
|
regs[r0] = *(int16_t *)ptr;
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-21 21:47:16 -08:00
|
|
|
case INDEX_op_ld:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
2025-01-21 21:47:16 -08:00
|
|
|
regs[r0] = *(tcg_target_ulong *)ptr;
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-22 13:28:55 -08:00
|
|
|
case INDEX_op_st8:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
|
|
|
|
*(uint8_t *)ptr = regs[r0];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-22 13:28:55 -08:00
|
|
|
case INDEX_op_st16:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
|
|
|
|
*(uint16_t *)ptr = regs[r0];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-22 13:28:55 -08:00
|
|
|
case INDEX_op_st:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
2025-01-22 13:28:55 -08:00
|
|
|
*(tcg_target_ulong *)ptr = regs[r0];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
|
|
|
|
|
2021-01-29 12:15:58 -10:00
|
|
|
/* Arithmetic operations (mixed 32/64 bit). */
|
2011-09-27 06:30:58 +02:00
|
|
|
|
2025-01-06 09:11:39 -08:00
|
|
|
case INDEX_op_add:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = regs[r1] + regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-06 22:06:32 -08:00
|
|
|
case INDEX_op_sub:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = regs[r1] - regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-07 09:32:18 -08:00
|
|
|
case INDEX_op_mul:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = regs[r1] * regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-06 10:32:44 -08:00
|
|
|
case INDEX_op_and:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = regs[r1] & regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-06 14:00:40 -08:00
|
|
|
case INDEX_op_or:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = regs[r1] | regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-06 15:18:35 -08:00
|
|
|
case INDEX_op_xor:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = regs[r1] ^ regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-06 12:37:02 -08:00
|
|
|
case INDEX_op_andc:
|
2021-02-02 16:29:18 -08:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
regs[r0] = regs[r1] & ~regs[r2];
|
|
|
|
|
break;
|
2025-01-06 14:46:26 -08:00
|
|
|
case INDEX_op_orc:
|
2021-02-02 16:29:18 -08:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
regs[r0] = regs[r1] | ~regs[r2];
|
|
|
|
|
break;
|
2025-01-06 15:47:53 -08:00
|
|
|
case INDEX_op_eqv:
|
2021-02-02 16:29:18 -08:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
regs[r0] = ~(regs[r1] ^ regs[r2]);
|
|
|
|
|
break;
|
2025-01-06 20:32:54 -08:00
|
|
|
case INDEX_op_nand:
|
2021-02-02 16:29:18 -08:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
regs[r0] = ~(regs[r1] & regs[r2]);
|
|
|
|
|
break;
|
2025-01-06 21:02:17 -08:00
|
|
|
case INDEX_op_nor:
|
2021-02-02 16:29:18 -08:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
regs[r0] = ~(regs[r1] | regs[r2]);
|
|
|
|
|
break;
|
2025-01-06 22:48:57 -08:00
|
|
|
case INDEX_op_neg:
|
|
|
|
|
tci_args_rr(insn, &r0, &r1);
|
|
|
|
|
regs[r0] = -regs[r1];
|
|
|
|
|
break;
|
2025-01-06 23:46:47 -08:00
|
|
|
case INDEX_op_not:
|
|
|
|
|
tci_args_rr(insn, &r0, &r1);
|
|
|
|
|
regs[r0] = ~regs[r1];
|
|
|
|
|
break;
|
2025-01-08 18:37:43 -08:00
|
|
|
case INDEX_op_ctpop:
|
2025-01-08 17:56:01 -08:00
|
|
|
tci_args_rr(insn, &r0, &r1);
|
2026-01-07 14:00:19 +11:00
|
|
|
regs[r0] = ctpop64(regs[r1]);
|
2025-01-08 17:56:01 -08:00
|
|
|
break;
|
2025-01-20 19:46:04 -08:00
|
|
|
case INDEX_op_addco:
|
|
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
t1 = regs[r1] + regs[r2];
|
|
|
|
|
carry = t1 < regs[r1];
|
|
|
|
|
regs[r0] = t1;
|
|
|
|
|
break;
|
|
|
|
|
case INDEX_op_addci:
|
|
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
regs[r0] = regs[r1] + regs[r2] + carry;
|
|
|
|
|
break;
|
|
|
|
|
case INDEX_op_addcio:
|
|
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
if (carry) {
|
|
|
|
|
t1 = regs[r1] + regs[r2] + 1;
|
|
|
|
|
carry = t1 <= regs[r1];
|
|
|
|
|
} else {
|
|
|
|
|
t1 = regs[r1] + regs[r2];
|
|
|
|
|
carry = t1 < regs[r1];
|
|
|
|
|
}
|
|
|
|
|
regs[r0] = t1;
|
|
|
|
|
break;
|
|
|
|
|
case INDEX_op_subbo:
|
|
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
carry = regs[r1] < regs[r2];
|
|
|
|
|
regs[r0] = regs[r1] - regs[r2];
|
|
|
|
|
break;
|
|
|
|
|
case INDEX_op_subbi:
|
|
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
regs[r0] = regs[r1] - regs[r2] - carry;
|
|
|
|
|
break;
|
|
|
|
|
case INDEX_op_subbio:
|
|
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
if (carry) {
|
|
|
|
|
carry = regs[r1] <= regs[r2];
|
|
|
|
|
regs[r0] = regs[r1] - regs[r2] - 1;
|
|
|
|
|
} else {
|
|
|
|
|
carry = regs[r1] < regs[r2];
|
|
|
|
|
regs[r0] = regs[r1] - regs[r2];
|
|
|
|
|
}
|
|
|
|
|
break;
|
2025-01-09 07:24:32 -08:00
|
|
|
case INDEX_op_muls2:
|
2025-01-08 21:52:03 -08:00
|
|
|
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
|
|
|
|
muls64(®s[r0], ®s[r1], regs[r2], regs[r3]);
|
2025-01-09 08:59:52 -08:00
|
|
|
break;
|
2025-01-09 09:11:53 -08:00
|
|
|
case INDEX_op_mulu2:
|
2025-01-09 08:59:52 -08:00
|
|
|
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
|
|
|
|
mulu64(®s[r0], ®s[r1], regs[r2], regs[r3]);
|
2025-01-08 21:52:03 -08:00
|
|
|
break;
|
2021-01-29 12:15:58 -10:00
|
|
|
|
|
|
|
|
/* Arithmetic operations (32 bit). */
|
|
|
|
|
|
2025-01-07 13:04:24 -08:00
|
|
|
case INDEX_op_tci_divs32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = (int32_t)regs[r1] / (int32_t)regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-07 14:10:27 -08:00
|
|
|
case INDEX_op_tci_divu32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = (uint32_t)regs[r1] / (uint32_t)regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-07 18:52:30 -08:00
|
|
|
case INDEX_op_tci_rems32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = (int32_t)regs[r1] % (int32_t)regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-07 20:12:08 -08:00
|
|
|
case INDEX_op_tci_remu32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = (uint32_t)regs[r1] % (uint32_t)regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-08 14:16:04 -08:00
|
|
|
case INDEX_op_tci_clz32:
|
2021-02-02 17:01:57 -08:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
tmp32 = regs[r1];
|
|
|
|
|
regs[r0] = tmp32 ? clz32(tmp32) : regs[r2];
|
|
|
|
|
break;
|
2025-01-08 17:02:13 -08:00
|
|
|
case INDEX_op_tci_ctz32:
|
2021-02-02 17:01:57 -08:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
tmp32 = regs[r1];
|
|
|
|
|
regs[r0] = tmp32 ? ctz32(tmp32) : regs[r2];
|
|
|
|
|
break;
|
2025-01-10 09:26:44 -08:00
|
|
|
case INDEX_op_tci_setcond32:
|
|
|
|
|
tci_args_rrrc(insn, &r0, &r1, &r2, &condition);
|
|
|
|
|
regs[r0] = tci_compare32(regs[r1], regs[r2], condition);
|
|
|
|
|
break;
|
2025-01-10 13:29:39 -08:00
|
|
|
case INDEX_op_tci_movcond32:
|
|
|
|
|
tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &condition);
|
|
|
|
|
tmp32 = tci_compare32(regs[r1], regs[r2], condition);
|
|
|
|
|
regs[r0] = regs[tmp32 ? r3 : r4];
|
|
|
|
|
break;
|
2011-09-27 06:30:58 +02:00
|
|
|
|
2025-01-07 21:50:04 -08:00
|
|
|
/* Shift/rotate operations. */
|
2011-09-27 06:30:58 +02:00
|
|
|
|
2025-01-07 21:50:04 -08:00
|
|
|
case INDEX_op_shl:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2025-01-07 21:50:04 -08:00
|
|
|
regs[r0] = regs[r1] << (regs[r2] % TCG_TARGET_REG_BITS);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-07 22:52:10 -08:00
|
|
|
case INDEX_op_shr:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2025-01-07 22:52:10 -08:00
|
|
|
regs[r0] = regs[r1] >> (regs[r2] % TCG_TARGET_REG_BITS);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-08 08:05:18 -08:00
|
|
|
case INDEX_op_sar:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2025-01-08 08:05:18 -08:00
|
|
|
regs[r0] = ((tcg_target_long)regs[r1]
|
|
|
|
|
>> (regs[r2] % TCG_TARGET_REG_BITS));
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-08 10:22:53 -08:00
|
|
|
case INDEX_op_tci_rotl32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = rol32(regs[r1], regs[r2] & 31);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-08 10:22:53 -08:00
|
|
|
case INDEX_op_tci_rotr32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = ror32(regs[r1], regs[r2] & 31);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-12 20:48:57 -08:00
|
|
|
case INDEX_op_deposit:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
|
2026-01-07 14:00:19 +11:00
|
|
|
regs[r0] = deposit64(regs[r1], pos, len, regs[r2]);
|
2012-09-18 22:52:14 +02:00
|
|
|
break;
|
2025-01-11 09:01:46 -08:00
|
|
|
case INDEX_op_extract:
|
2021-02-02 16:48:48 -08:00
|
|
|
tci_args_rrbb(insn, &r0, &r1, &pos, &len);
|
2026-01-07 14:00:19 +11:00
|
|
|
regs[r0] = extract64(regs[r1], pos, len);
|
2021-02-02 16:48:48 -08:00
|
|
|
break;
|
2025-01-12 11:50:09 -08:00
|
|
|
case INDEX_op_sextract:
|
2021-02-02 16:48:48 -08:00
|
|
|
tci_args_rrbb(insn, &r0, &r1, &pos, &len);
|
2026-01-07 14:00:19 +11:00
|
|
|
regs[r0] = sextract64(regs[r1], pos, len);
|
2021-02-02 16:48:48 -08:00
|
|
|
break;
|
2025-01-10 11:49:22 -08:00
|
|
|
case INDEX_op_brcond:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rl(insn, tb_ptr, &r0, &ptr);
|
2025-01-10 11:40:06 -08:00
|
|
|
if (regs[r0]) {
|
2021-01-29 21:41:13 -10:00
|
|
|
tb_ptr = ptr;
|
2011-09-27 06:30:58 +02:00
|
|
|
}
|
|
|
|
|
break;
|
2025-01-10 18:51:16 -08:00
|
|
|
case INDEX_op_bswap16:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rr(insn, &r0, &r1);
|
2021-01-29 13:05:01 -10:00
|
|
|
regs[r0] = bswap16(regs[r1]);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-10 19:53:51 -08:00
|
|
|
case INDEX_op_bswap32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rr(insn, &r0, &r1);
|
2021-01-29 13:05:01 -10:00
|
|
|
regs[r0] = bswap32(regs[r1]);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2026-01-07 12:52:50 +11:00
|
|
|
|
2011-09-27 06:30:58 +02:00
|
|
|
/* Load/store operations (64 bit). */
|
|
|
|
|
|
2025-01-21 21:47:16 -08:00
|
|
|
case INDEX_op_ld32u:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
2025-01-21 21:47:16 -08:00
|
|
|
regs[r0] = *(uint32_t *)ptr;
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-21 21:47:16 -08:00
|
|
|
case INDEX_op_ld32s:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
2025-01-21 21:47:16 -08:00
|
|
|
regs[r0] = *(int32_t *)ptr;
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-22 13:28:55 -08:00
|
|
|
case INDEX_op_st32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &ofs);
|
2021-01-29 12:55:41 -10:00
|
|
|
ptr = (void *)(regs[r1] + ofs);
|
2025-01-22 13:28:55 -08:00
|
|
|
*(uint32_t *)ptr = regs[r0];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* Arithmetic operations (64 bit). */
|
|
|
|
|
|
2025-01-07 13:22:56 -08:00
|
|
|
case INDEX_op_divs:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = (int64_t)regs[r1] / (int64_t)regs[r2];
|
2021-01-27 20:30:00 -10:00
|
|
|
break;
|
2025-01-07 14:27:19 -08:00
|
|
|
case INDEX_op_divu:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = (uint64_t)regs[r1] / (uint64_t)regs[r2];
|
2021-01-27 20:30:00 -10:00
|
|
|
break;
|
2025-01-07 19:00:51 -08:00
|
|
|
case INDEX_op_rems:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = (int64_t)regs[r1] % (int64_t)regs[r2];
|
2021-01-27 20:30:00 -10:00
|
|
|
break;
|
2025-01-07 20:25:14 -08:00
|
|
|
case INDEX_op_remu:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = (uint64_t)regs[r1] % (uint64_t)regs[r2];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-08 16:12:46 -08:00
|
|
|
case INDEX_op_clz:
|
2021-02-02 17:01:57 -08:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
regs[r0] = regs[r1] ? clz64(regs[r1]) : regs[r2];
|
|
|
|
|
break;
|
2025-01-08 17:07:01 -08:00
|
|
|
case INDEX_op_ctz:
|
2021-02-02 17:01:57 -08:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
regs[r0] = regs[r1] ? ctz64(regs[r1]) : regs[r2];
|
|
|
|
|
break;
|
2011-09-27 06:30:58 +02:00
|
|
|
|
|
|
|
|
/* Shift/rotate operations (64 bit). */
|
|
|
|
|
|
2025-01-08 10:42:16 -08:00
|
|
|
case INDEX_op_rotl:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = rol64(regs[r1], regs[r2] & 63);
|
2013-09-12 21:13:11 +02:00
|
|
|
break;
|
2025-01-08 10:42:16 -08:00
|
|
|
case INDEX_op_rotr:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-29 13:10:28 -10:00
|
|
|
regs[r0] = ror64(regs[r1], regs[r2] & 63);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2015-07-27 12:41:45 +02:00
|
|
|
case INDEX_op_ext_i32_i64:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rr(insn, &r0, &r1);
|
2021-01-29 13:05:01 -10:00
|
|
|
regs[r0] = (int32_t)regs[r1];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2015-07-27 12:41:45 +02:00
|
|
|
case INDEX_op_extu_i32_i64:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rr(insn, &r0, &r1);
|
2021-01-29 13:05:01 -10:00
|
|
|
regs[r0] = (uint32_t)regs[r1];
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-01-10 21:54:44 -08:00
|
|
|
case INDEX_op_bswap64:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rr(insn, &r0, &r1);
|
2021-01-29 13:05:01 -10:00
|
|
|
regs[r0] = bswap64(regs[r1]);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* QEMU specific operations. */
|
|
|
|
|
|
|
|
|
|
case INDEX_op_exit_tb:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_l(insn, tb_ptr, &ptr);
|
2021-01-29 22:01:11 -10:00
|
|
|
return (uintptr_t)ptr;
|
|
|
|
|
|
2011-09-27 06:30:58 +02:00
|
|
|
case INDEX_op_goto_tb:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_l(insn, tb_ptr, &ptr);
|
2021-01-29 22:11:43 -10:00
|
|
|
tb_ptr = *(void **)ptr;
|
2021-01-30 13:23:02 -08:00
|
|
|
break;
|
2021-01-29 22:11:43 -10:00
|
|
|
|
2021-02-02 09:40:22 -10:00
|
|
|
case INDEX_op_goto_ptr:
|
|
|
|
|
tci_args_r(insn, &r0);
|
|
|
|
|
ptr = (void *)regs[r0];
|
|
|
|
|
if (!ptr) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
tb_ptr = ptr;
|
|
|
|
|
break;
|
|
|
|
|
|
2025-02-09 12:55:15 -08:00
|
|
|
case INDEX_op_qemu_ld:
|
2023-03-20 07:48:09 -07:00
|
|
|
tci_args_rrm(insn, &r0, &r1, &oi);
|
2025-02-04 13:46:09 -08:00
|
|
|
taddr = regs[r1];
|
2023-03-20 07:48:09 -07:00
|
|
|
regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-12-01 14:02:41 -08:00
|
|
|
case INDEX_op_tci_qemu_ld_rrr:
|
|
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
taddr = regs[r1];
|
|
|
|
|
oi = regs[r2];
|
|
|
|
|
regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr);
|
|
|
|
|
break;
|
2021-01-29 22:52:12 -10:00
|
|
|
|
2025-02-09 12:55:15 -08:00
|
|
|
case INDEX_op_qemu_st:
|
2023-03-20 07:48:09 -07:00
|
|
|
tci_args_rrm(insn, &r0, &r1, &oi);
|
2025-02-04 13:46:09 -08:00
|
|
|
taddr = regs[r1];
|
2023-03-20 07:48:09 -07:00
|
|
|
tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
|
2011-09-27 06:30:58 +02:00
|
|
|
break;
|
2025-12-01 14:02:41 -08:00
|
|
|
case INDEX_op_tci_qemu_st_rrr:
|
|
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
taddr = regs[r1];
|
|
|
|
|
oi = regs[r2];
|
|
|
|
|
tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr);
|
|
|
|
|
break;
|
2021-01-29 22:52:12 -10:00
|
|
|
|
2016-07-14 16:20:22 -04:00
|
|
|
case INDEX_op_mb:
|
|
|
|
|
/* Ensure ordering for all kinds */
|
|
|
|
|
smp_mb();
|
|
|
|
|
break;
|
2011-09-27 06:30:58 +02:00
|
|
|
default:
|
2021-01-27 20:11:11 -10:00
|
|
|
g_assert_not_reached();
|
2011-09-27 06:30:58 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-30 17:48:19 -08:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Disassembler that matches the interpreter
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
static const char *str_r(TCGReg r)
|
|
|
|
|
{
|
|
|
|
|
static const char regs[TCG_TARGET_NB_REGS][4] = {
|
|
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
|
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "env", "sp"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
QEMU_BUILD_BUG_ON(TCG_AREG0 != TCG_REG_R14);
|
|
|
|
|
QEMU_BUILD_BUG_ON(TCG_REG_CALL_STACK != TCG_REG_R15);
|
|
|
|
|
|
|
|
|
|
assert((unsigned)r < TCG_TARGET_NB_REGS);
|
|
|
|
|
return regs[r];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *str_c(TCGCond c)
|
|
|
|
|
{
|
|
|
|
|
static const char cond[16][8] = {
|
|
|
|
|
[TCG_COND_NEVER] = "never",
|
|
|
|
|
[TCG_COND_ALWAYS] = "always",
|
|
|
|
|
[TCG_COND_EQ] = "eq",
|
|
|
|
|
[TCG_COND_NE] = "ne",
|
|
|
|
|
[TCG_COND_LT] = "lt",
|
|
|
|
|
[TCG_COND_GE] = "ge",
|
|
|
|
|
[TCG_COND_LE] = "le",
|
|
|
|
|
[TCG_COND_GT] = "gt",
|
|
|
|
|
[TCG_COND_LTU] = "ltu",
|
|
|
|
|
[TCG_COND_GEU] = "geu",
|
|
|
|
|
[TCG_COND_LEU] = "leu",
|
|
|
|
|
[TCG_COND_GTU] = "gtu",
|
2023-10-24 22:52:26 -07:00
|
|
|
[TCG_COND_TSTEQ] = "tsteq",
|
|
|
|
|
[TCG_COND_TSTNE] = "tstne",
|
2021-01-30 17:48:19 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
assert((unsigned)c < ARRAY_SIZE(cond));
|
|
|
|
|
assert(cond[c][0] != 0);
|
|
|
|
|
return cond[c];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Disassemble TCI bytecode. */
|
|
|
|
|
int print_insn_tci(bfd_vma addr, disassemble_info *info)
|
|
|
|
|
{
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
const uint32_t *tb_ptr = (const void *)(uintptr_t)addr;
|
2021-01-30 17:48:19 -08:00
|
|
|
const TCGOpDef *def;
|
|
|
|
|
const char *op_name;
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
uint32_t insn;
|
2021-01-30 17:48:19 -08:00
|
|
|
TCGOpcode op;
|
2025-01-20 19:46:04 -08:00
|
|
|
TCGReg r0, r1, r2, r3, r4;
|
2021-01-30 17:48:19 -08:00
|
|
|
tcg_target_ulong i1;
|
|
|
|
|
int32_t s2;
|
|
|
|
|
TCGCond c;
|
2021-07-25 12:06:49 -10:00
|
|
|
MemOpIdx oi;
|
2021-01-30 17:48:19 -08:00
|
|
|
uint8_t pos, len;
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
void *ptr;
|
2021-01-30 17:48:19 -08:00
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
/* TCI is always the host, so we don't need to load indirect. */
|
|
|
|
|
insn = *tb_ptr++;
|
2021-01-30 17:48:19 -08:00
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
info->fprintf_func(info->stream, "%08x ", insn);
|
2021-01-30 17:48:19 -08:00
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
op = extract32(insn, 0, 8);
|
2021-01-30 17:48:19 -08:00
|
|
|
def = &tcg_op_defs[op];
|
|
|
|
|
op_name = def->name;
|
|
|
|
|
|
|
|
|
|
switch (op) {
|
|
|
|
|
case INDEX_op_br:
|
|
|
|
|
case INDEX_op_exit_tb:
|
|
|
|
|
case INDEX_op_goto_tb:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_l(insn, tb_ptr, &ptr);
|
2021-01-30 17:48:19 -08:00
|
|
|
info->fprintf_func(info->stream, "%-12s %p", op_name, ptr);
|
|
|
|
|
break;
|
|
|
|
|
|
2021-02-02 09:40:22 -10:00
|
|
|
case INDEX_op_goto_ptr:
|
|
|
|
|
tci_args_r(insn, &r0);
|
|
|
|
|
info->fprintf_func(info->stream, "%-12s %s", op_name, str_r(r0));
|
|
|
|
|
break;
|
|
|
|
|
|
2021-01-30 14:24:25 -08:00
|
|
|
case INDEX_op_call:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_nl(insn, tb_ptr, &len, &ptr);
|
|
|
|
|
info->fprintf_func(info->stream, "%-12s %d, %p", op_name, len, ptr);
|
2021-01-30 14:24:25 -08:00
|
|
|
break;
|
|
|
|
|
|
2025-01-10 11:49:22 -08:00
|
|
|
case INDEX_op_brcond:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rl(insn, tb_ptr, &r0, &ptr);
|
2021-02-01 09:41:20 -10:00
|
|
|
info->fprintf_func(info->stream, "%-12s %s, 0, ne, %p",
|
|
|
|
|
op_name, str_r(r0), ptr);
|
2021-01-30 17:48:19 -08:00
|
|
|
break;
|
|
|
|
|
|
2025-01-10 09:26:44 -08:00
|
|
|
case INDEX_op_setcond:
|
|
|
|
|
case INDEX_op_tci_setcond32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrrc(insn, &r0, &r1, &r2, &c);
|
2021-01-30 17:48:19 -08:00
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
|
|
|
|
|
op_name, str_r(r0), str_r(r1), str_r(r2), str_c(c));
|
|
|
|
|
break;
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
case INDEX_op_tci_movi:
|
|
|
|
|
tci_args_ri(insn, &r0, &i1);
|
2021-01-30 17:48:19 -08:00
|
|
|
info->fprintf_func(info->stream, "%-12s %s, 0x%" TCG_PRIlx,
|
|
|
|
|
op_name, str_r(r0), i1);
|
|
|
|
|
break;
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
case INDEX_op_tci_movl:
|
|
|
|
|
tci_args_rl(insn, tb_ptr, &r0, &ptr);
|
|
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %p",
|
|
|
|
|
op_name, str_r(r0), ptr);
|
2021-01-30 17:48:19 -08:00
|
|
|
break;
|
|
|
|
|
|
2025-01-20 19:46:04 -08:00
|
|
|
case INDEX_op_tci_setcarry:
|
|
|
|
|
info->fprintf_func(info->stream, "%-12s", op_name);
|
|
|
|
|
break;
|
|
|
|
|
|
2025-01-21 21:47:16 -08:00
|
|
|
case INDEX_op_ld8u:
|
|
|
|
|
case INDEX_op_ld8s:
|
|
|
|
|
case INDEX_op_ld16u:
|
|
|
|
|
case INDEX_op_ld16s:
|
|
|
|
|
case INDEX_op_ld32u:
|
|
|
|
|
case INDEX_op_ld:
|
2025-01-22 13:28:55 -08:00
|
|
|
case INDEX_op_st8:
|
|
|
|
|
case INDEX_op_st16:
|
|
|
|
|
case INDEX_op_st32:
|
|
|
|
|
case INDEX_op_st:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrs(insn, &r0, &r1, &s2);
|
2021-01-30 17:48:19 -08:00
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s, %d",
|
|
|
|
|
op_name, str_r(r0), str_r(r1), s2);
|
|
|
|
|
break;
|
|
|
|
|
|
2025-01-10 18:51:16 -08:00
|
|
|
case INDEX_op_bswap16:
|
2025-01-10 19:53:51 -08:00
|
|
|
case INDEX_op_bswap32:
|
2025-01-08 18:37:43 -08:00
|
|
|
case INDEX_op_ctpop:
|
2024-12-28 15:58:24 -08:00
|
|
|
case INDEX_op_mov:
|
2025-01-06 22:48:57 -08:00
|
|
|
case INDEX_op_neg:
|
2025-01-06 23:46:47 -08:00
|
|
|
case INDEX_op_not:
|
2021-01-30 17:48:19 -08:00
|
|
|
case INDEX_op_ext_i32_i64:
|
|
|
|
|
case INDEX_op_extu_i32_i64:
|
2025-01-10 21:54:44 -08:00
|
|
|
case INDEX_op_bswap64:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rr(insn, &r0, &r1);
|
2021-01-30 17:48:19 -08:00
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s",
|
|
|
|
|
op_name, str_r(r0), str_r(r1));
|
|
|
|
|
break;
|
|
|
|
|
|
2025-01-06 09:11:39 -08:00
|
|
|
case INDEX_op_add:
|
2025-01-20 19:46:04 -08:00
|
|
|
case INDEX_op_addci:
|
|
|
|
|
case INDEX_op_addcio:
|
|
|
|
|
case INDEX_op_addco:
|
2025-01-06 10:32:44 -08:00
|
|
|
case INDEX_op_and:
|
2025-01-06 12:37:02 -08:00
|
|
|
case INDEX_op_andc:
|
2025-01-08 16:12:46 -08:00
|
|
|
case INDEX_op_clz:
|
2025-01-08 17:07:01 -08:00
|
|
|
case INDEX_op_ctz:
|
2025-01-07 13:22:56 -08:00
|
|
|
case INDEX_op_divs:
|
2025-01-07 14:27:19 -08:00
|
|
|
case INDEX_op_divu:
|
2025-01-06 15:47:53 -08:00
|
|
|
case INDEX_op_eqv:
|
2025-01-07 09:32:18 -08:00
|
|
|
case INDEX_op_mul:
|
2025-01-06 20:32:54 -08:00
|
|
|
case INDEX_op_nand:
|
2025-01-06 21:02:17 -08:00
|
|
|
case INDEX_op_nor:
|
2025-01-06 14:00:40 -08:00
|
|
|
case INDEX_op_or:
|
2025-01-06 14:46:26 -08:00
|
|
|
case INDEX_op_orc:
|
2025-01-07 19:00:51 -08:00
|
|
|
case INDEX_op_rems:
|
2025-01-07 20:25:14 -08:00
|
|
|
case INDEX_op_remu:
|
2025-01-08 10:42:16 -08:00
|
|
|
case INDEX_op_rotl:
|
|
|
|
|
case INDEX_op_rotr:
|
2025-01-08 08:05:18 -08:00
|
|
|
case INDEX_op_sar:
|
2025-01-07 21:50:04 -08:00
|
|
|
case INDEX_op_shl:
|
2025-01-07 22:52:10 -08:00
|
|
|
case INDEX_op_shr:
|
2025-01-06 22:06:32 -08:00
|
|
|
case INDEX_op_sub:
|
2025-01-20 19:46:04 -08:00
|
|
|
case INDEX_op_subbi:
|
|
|
|
|
case INDEX_op_subbio:
|
|
|
|
|
case INDEX_op_subbo:
|
2025-01-06 15:18:35 -08:00
|
|
|
case INDEX_op_xor:
|
2025-01-08 17:02:13 -08:00
|
|
|
case INDEX_op_tci_ctz32:
|
2025-01-08 14:16:04 -08:00
|
|
|
case INDEX_op_tci_clz32:
|
2025-01-07 13:04:24 -08:00
|
|
|
case INDEX_op_tci_divs32:
|
2025-01-07 14:10:27 -08:00
|
|
|
case INDEX_op_tci_divu32:
|
2025-01-07 18:52:30 -08:00
|
|
|
case INDEX_op_tci_rems32:
|
2025-01-07 20:12:08 -08:00
|
|
|
case INDEX_op_tci_remu32:
|
2025-01-08 10:22:53 -08:00
|
|
|
case INDEX_op_tci_rotl32:
|
|
|
|
|
case INDEX_op_tci_rotr32:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
2021-01-30 17:48:19 -08:00
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s, %s",
|
|
|
|
|
op_name, str_r(r0), str_r(r1), str_r(r2));
|
|
|
|
|
break;
|
|
|
|
|
|
2025-01-12 20:48:57 -08:00
|
|
|
case INDEX_op_deposit:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrrbb(insn, &r0, &r1, &r2, &pos, &len);
|
2021-01-30 17:48:19 -08:00
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %d, %d",
|
|
|
|
|
op_name, str_r(r0), str_r(r1), str_r(r2), pos, len);
|
|
|
|
|
break;
|
|
|
|
|
|
2025-01-11 09:01:46 -08:00
|
|
|
case INDEX_op_extract:
|
2025-01-12 11:50:09 -08:00
|
|
|
case INDEX_op_sextract:
|
2021-02-02 16:48:48 -08:00
|
|
|
tci_args_rrbb(insn, &r0, &r1, &pos, &len);
|
|
|
|
|
info->fprintf_func(info->stream, "%-12s %s,%s,%d,%d",
|
|
|
|
|
op_name, str_r(r0), str_r(r1), pos, len);
|
|
|
|
|
break;
|
|
|
|
|
|
2025-01-10 13:29:39 -08:00
|
|
|
case INDEX_op_tci_movcond32:
|
2025-01-10 13:41:25 -08:00
|
|
|
case INDEX_op_movcond:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrrrrc(insn, &r0, &r1, &r2, &r3, &r4, &c);
|
2021-01-30 17:48:19 -08:00
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s, %s, %s",
|
|
|
|
|
op_name, str_r(r0), str_r(r1), str_r(r2),
|
|
|
|
|
str_r(r3), str_r(r4), str_c(c));
|
|
|
|
|
break;
|
|
|
|
|
|
2025-01-09 07:24:32 -08:00
|
|
|
case INDEX_op_muls2:
|
2025-01-09 09:11:53 -08:00
|
|
|
case INDEX_op_mulu2:
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
2021-01-30 17:48:19 -08:00
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
|
|
|
|
|
op_name, str_r(r0), str_r(r1),
|
|
|
|
|
str_r(r2), str_r(r3));
|
|
|
|
|
break;
|
|
|
|
|
|
2025-02-09 12:55:15 -08:00
|
|
|
case INDEX_op_qemu_ld:
|
|
|
|
|
case INDEX_op_qemu_st:
|
2025-02-04 13:46:09 -08:00
|
|
|
tci_args_rrm(insn, &r0, &r1, &oi);
|
|
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s, %x",
|
|
|
|
|
op_name, str_r(r0), str_r(r1), oi);
|
2021-01-30 17:48:19 -08:00
|
|
|
break;
|
|
|
|
|
|
2025-12-01 14:02:41 -08:00
|
|
|
case INDEX_op_tci_qemu_ld_rrr:
|
|
|
|
|
case INDEX_op_tci_qemu_st_rrr:
|
|
|
|
|
tci_args_rrr(insn, &r0, &r1, &r2);
|
|
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s, %s",
|
|
|
|
|
op_name, str_r(r0), str_r(r1), str_r(r2));
|
|
|
|
|
break;
|
|
|
|
|
|
2025-02-09 12:55:15 -08:00
|
|
|
case INDEX_op_qemu_ld2:
|
|
|
|
|
case INDEX_op_qemu_st2:
|
|
|
|
|
tci_args_rrrr(insn, &r0, &r1, &r2, &r3);
|
|
|
|
|
info->fprintf_func(info->stream, "%-12s %s, %s, %s, %s",
|
|
|
|
|
op_name, str_r(r0), str_r(r1),
|
|
|
|
|
str_r(r2), str_r(r3));
|
|
|
|
|
break;
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
case 0:
|
|
|
|
|
/* tcg_out_nop_fill uses zeros */
|
|
|
|
|
if (insn == 0) {
|
|
|
|
|
info->fprintf_func(info->stream, "align");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
/* fall through */
|
|
|
|
|
|
2021-01-30 17:48:19 -08:00
|
|
|
default:
|
|
|
|
|
info->fprintf_func(info->stream, "illegal opcode %d", op);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
tcg/tci: Change encoding to uint32_t units
This removes all of the problems with unaligned accesses
to the bytecode stream.
With an 8-bit opcode at the bottom, we have 24 bits remaining,
which are generally split into 6 4-bit slots. This fits well
with the maximum length opcodes, e.g. INDEX_op_add2_i32, which
have 6 register operands.
We have, in previous patches, rearranged things such that there
are no operations with a label which have more than one other
operand. Which leaves us with a 20-bit field in which to encode
a label, giving us a maximum TB size of 512k -- easily large.
Change the INDEX_op_tci_movi_{i32,i64} opcodes to tci_mov[il].
The former puts the immediate in the upper 20 bits of the insn,
like we do for the label displacement. The later uses a label
to reference an entry in the constant pool. Thus, in the worst
case we still have a single memory reference for any constant,
but now the constants are out-of-line of the bytecode and can
be shared between different moves saving space.
Change INDEX_op_call to use a label to reference a pair of
pointers in the constant pool. This removes the only slightly
dodgy link with the layout of struct TCGHelperInfo.
The re-encode cannot be done in pieces.
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2021-02-01 21:27:41 -10:00
|
|
|
return sizeof(insn);
|
2021-01-30 17:48:19 -08:00
|
|
|
}
|