[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 7/7] tcg/mips: Support r6 SEL{NE, EQ}Z instead of MO
From: |
James Hogan |
Subject: |
[Qemu-devel] [PATCH 7/7] tcg/mips: Support r6 SEL{NE, EQ}Z instead of MOVN/MOVZ |
Date: |
Wed, 30 Sep 2015 16:30:27 +0100 |
Extend MIPS movcond implementation to support the SELNEZ/SELEQZ
instructions introduced in MIPS r6 (where MOVN/MOVZ have been removed).
Whereas the "MOVN/MOVZ rd, rs, rt" instructions have the following
semantics:
rd = [!]rt ? rs : rd
The "SELNEZ/SELEQZ rd, rs, rt" instructions are slightly different:
rd = [!]rt ? rs : 0
First we ensure that if one of the movcond input values is zero that it
comes last (we can swap the input arguments if we invert the condition).
This is so that it can exactly match one of the SELNEZ/SELEQZ
instructions and avoid the need to emit the other one.
Otherwise we emit the opposite instruction first into a temporary
register, and OR that into the result:
SELNEZ/SELEQZ TMP1, v2, c1
SELEQZ/SELNEZ ret, v1, c1
OR ret, ret, TMP1
Which does the following:
ret = cond ? v1 : v2
Signed-off-by: James Hogan <address@hidden>
Cc: Richard Henderson <address@hidden>
Cc: Aurelien Jarno <address@hidden>
---
tcg/mips/tcg-target.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 9849896bd75b..6c0159f4a38d 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -314,6 +314,8 @@ typedef enum {
OPC_NOR = OPC_SPECIAL | 0x27,
OPC_SLT = OPC_SPECIAL | 0x2A,
OPC_SLTU = OPC_SPECIAL | 0x2B,
+ OPC_SELEQZ = OPC_SPECIAL | 0x35,
+ OPC_SELNEZ = OPC_SPECIAL | 0x37,
OPC_REGIMM = 0x01 << 26,
OPC_BLTZ = OPC_REGIMM | (0x00 << 16),
@@ -854,11 +856,18 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond,
TCGReg al, TCGReg ah,
static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
TCGReg c1, TCGReg c2, TCGReg v1, TCGReg v2)
{
- MIPSInsn m_opc_t = OPC_MOVN;
- MIPSInsn m_opc_f = OPC_MOVZ;
+ MIPSInsn m_opc_t = use_mips32r6_instructions ? OPC_SELNEZ : OPC_MOVN;
+ MIPSInsn m_opc_f = use_mips32r6_instructions ? OPC_SELEQZ : OPC_MOVZ;
const MIPSInsn m_opc_t_inv = m_opc_f;
const MIPSInsn m_opc_f_inv = m_opc_t;
+ /* If one of the values is zero, put it last to match SEL*Z instructions */
+ if (use_mips32r6_instructions && v1 == 0) {
+ v1 = v2;
+ v2 = 0;
+ cond = tcg_invert_cond(cond);
+ }
+
switch (cond) {
case TCG_COND_EQ:
m_opc_t = m_opc_t_inv;
@@ -883,11 +892,21 @@ static void tcg_out_movcond(TCGContext *s, TCGCond cond,
TCGReg ret,
break;
}
- if (v1 != ret) {
+ if (use_mips32r6_instructions) {
+ if (v2 != 0) {
+ tcg_out_opc_reg(s, m_opc_f, TCG_TMP1, v2, c1);
+ }
tcg_out_opc_reg(s, m_opc_t, ret, v1, c1);
- }
- if (v2 != ret) {
- tcg_out_opc_reg(s, m_opc_f, ret, v2, c1);
+ if (v2 != 0) {
+ tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_TMP1);
+ }
+ } else {
+ if (v1 != ret) {
+ tcg_out_opc_reg(s, m_opc_t, ret, v1, c1);
+ }
+ if (v2 != ret) {
+ tcg_out_opc_reg(s, m_opc_f, ret, v2, c1);
+ }
}
}
--
2.4.9
- [Qemu-devel] [PATCH 0/7] tcg/mips: Minimal R6 support, James Hogan, 2015/10/08
- [Qemu-devel] [PATCH 7/7] tcg/mips: Support r6 SEL{NE, EQ}Z instead of MOVN/MOVZ,
James Hogan <=
- [Qemu-devel] [PATCH 3/7] tcg/mips: Add use_mips32r6_instructions definition, James Hogan, 2015/10/08
- [Qemu-devel] [PATCH 2/7] disas/mips: Add R6 jr/jr.hb to disassembler, James Hogan, 2015/10/08
- [Qemu-devel] [PATCH 5/7] tcg/mips: Support r6 multiply/divide encodings, James Hogan, 2015/10/08
- [Qemu-devel] [PATCH 4/7] tcg/mips: Support r6 JR encoding, James Hogan, 2015/10/08
- [Qemu-devel] [PATCH 6/7] tcg/mips: Support full movcond select operation, James Hogan, 2015/10/08