1409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/*
2409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli *  MIPS emulation helpers for qemu.
3409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli *
4409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli *  Copyright (c) 2004-2005 Jocelyn Mayer
5409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli *
6409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * This library is free software; you can redistribute it and/or
7409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * modify it under the terms of the GNU Lesser General Public
8409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * License as published by the Free Software Foundation; either
9409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * version 2 of the License, or (at your option) any later version.
10409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli *
11409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * This library is distributed in the hope that it will be useful,
12409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * but WITHOUT ANY WARRANTY; without even the implied warranty of
13409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * Lesser General Public License for more details.
15409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli *
16409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * You should have received a copy of the GNU Lesser General Public
17409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli */
19409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include <stdlib.h>
20a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner#include "cpu.h"
21e90d665cd63a0bc5c3306e1ee3e98ad362546b16David 'Digit' Turner#include "qemu/host-utils.h"
2286b1fb06ee6ef53d8961ce96343ba4aa37518840David 'Digit' Turner#include "tcg.h"
23409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "helper.h"
24a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner
25a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner#if !defined(CONFIG_USER_ONLY)
26a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner#include "exec/softmmu_exec.h"
27a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner#endif /* !defined(CONFIG_USER_ONLY) */
28a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner
29a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner#ifndef CONFIG_USER_ONLY
30a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turnerstatic inline void cpu_mips_tlb_flush (CPUMIPSState *env, int flush_global);
31a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner#endif
32a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner
33a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turnerstatic inline void compute_hflags(CPUMIPSState *env)
34a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner{
35a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
36a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner                     MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
37a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner                     MIPS_HFLAG_UX);
38a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
39a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        !(env->CP0_Status & (1 << CP0St_ERL)) &&
40a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        !(env->hflags & MIPS_HFLAG_DM)) {
41a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
42a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    }
43a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner#if defined(TARGET_MIPS64)
44a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
45a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        (env->CP0_Status & (1 << CP0St_PX)) ||
46a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        (env->CP0_Status & (1 << CP0St_UX))) {
47a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        env->hflags |= MIPS_HFLAG_64;
48a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    }
49a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    if (env->CP0_Status & (1 << CP0St_UX)) {
50a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        env->hflags |= MIPS_HFLAG_UX;
51a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    }
52a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner#endif
53a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    if ((env->CP0_Status & (1 << CP0St_CU0)) ||
54a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        !(env->hflags & MIPS_HFLAG_KSU)) {
55a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        env->hflags |= MIPS_HFLAG_CP0;
56a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    }
57a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    if (env->CP0_Status & (1 << CP0St_CU1)) {
58a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        env->hflags |= MIPS_HFLAG_FPU;
59a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    }
60a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    if (env->CP0_Status & (1 << CP0St_FR)) {
61a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        env->hflags |= MIPS_HFLAG_F64;
62a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    }
63a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    if (env->insn_flags & ISA_MIPS32R2) {
64a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
65a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner            env->hflags |= MIPS_HFLAG_COP1X;
66a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        }
67a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    } else if (env->insn_flags & ISA_MIPS32) {
68a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        if (env->hflags & MIPS_HFLAG_64) {
69a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner            env->hflags |= MIPS_HFLAG_COP1X;
70a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        }
71a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    } else if (env->insn_flags & ISA_MIPS4) {
72a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        /* All supported MIPS IV CPUs use the XX (CU3) to enable
73a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner           and disable the MIPS IV extensions to the MIPS III ISA.
74a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner           Some other MIPS IV CPUs ignore the bit, so the check here
75a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner           would be too restrictive for them.  */
76a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        if (env->CP0_Status & (1 << CP0St_CU3)) {
77a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner            env->hflags |= MIPS_HFLAG_COP1X;
78a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner        }
79a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner    }
80a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner}
81a889d35e76c8ea18caf70c738fd585c64b857369David 'Digit' Turner
82409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/*****************************************************************************/
83409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* Exceptions processing helpers */
84409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
856480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnervoid helper_raise_exception_err (CPUMIPSState *env,
866480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner                                 uint32_t exception, int error_code)
87409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
88409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if 1
89409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (exception < 0x100)
90409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        qemu_log("%s: %d %d\n", __func__, exception, error_code);
91409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
92409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->exception_index = exception;
93409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->error_code = error_code;
9485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner    cpu_loop_exit(env);
95409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
96409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
976480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnervoid helper_raise_exception (CPUMIPSState *env, uint32_t exception)
98409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
996480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner    helper_raise_exception_err(env, exception, 0);
100409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
101409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1026480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnervoid helper_interrupt_restart (CPUMIPSState *env)
103409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
104409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
105409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        !(env->CP0_Status & (1 << CP0St_ERL)) &&
106409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        !(env->hflags & MIPS_HFLAG_DM) &&
107409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        (env->CP0_Status & (1 << CP0St_IE)) &&
108409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
109409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
1106480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_EXT_INTERRUPT);
111409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
112409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
113409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
114409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if !defined(CONFIG_USER_ONLY)
1156480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnerstatic void do_restore_state (CPUMIPSState *env, uintptr_t pc)
116409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
117409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    TranslationBlock *tb;
118c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner
119409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tb = tb_find_pc (pc);
120409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (tb) {
1213e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner        cpu_restore_state (env, pc);
122409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
123409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
124409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
125409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
126409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if defined(CONFIG_USER_ONLY)
127409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define HELPER_LD(name, insn, type)                                     \
128d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnerstatic inline type do_##name(CPUMIPSState *env, target_ulong addr,      \
129d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                             int mem_idx)                               \
130409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                       \
131eca7bc24e45fb6809582795ff88f13384b5ce7dfDavid 'Digit' Turner    return (type) cpu_##insn##_raw(env, addr);                                     \
132409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
133409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#else
134409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define HELPER_LD(name, insn, type)                                     \
135d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnerstatic inline type do_##name(CPUMIPSState *env, target_ulong addr,      \
136d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                             int mem_idx)                               \
137409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                       \
138409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    switch (mem_idx)                                                    \
139409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    {                                                                   \
140d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    case 0: return (type) cpu_##insn##_kernel(env, addr); break;        \
141d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    case 1: return (type) cpu_##insn##_super(env, addr); break;         \
142409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    default:                                                            \
143d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    case 2: return (type) cpu_##insn##_user(env, addr); break;          \
144409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }                                                                   \
145409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
146409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
147409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_LD(lbu, ldub, uint8_t)
148409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_LD(lw, ldl, int32_t)
149409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifdef TARGET_MIPS64
150409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_LD(ld, ldq, int64_t)
151409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
152409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#undef HELPER_LD
153409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
154409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if defined(CONFIG_USER_ONLY)
155409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define HELPER_ST(name, insn, type)                                     \
156d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnerstatic inline void do_##name(CPUMIPSState *env, target_ulong addr,      \
157d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                             type val, int mem_idx)                     \
158409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                       \
159eca7bc24e45fb6809582795ff88f13384b5ce7dfDavid 'Digit' Turner    cpu_##insn##_raw(env, addr, val);                                              \
160409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
161409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#else
162409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define HELPER_ST(name, insn, type)                                     \
163d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnerstatic inline void do_##name(CPUMIPSState *env, target_ulong addr,      \
164d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                             type val, int mem_idx)                     \
165409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                       \
166409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    switch (mem_idx)                                                    \
167409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    {                                                                   \
168d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    case 0: cpu_##insn##_kernel(env, addr, val); break;                 \
169d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    case 1: cpu_##insn##_super(env, addr, val); break;                  \
170409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    default:                                                            \
171d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    case 2: cpu_##insn##_user(env, addr, val); break;                   \
172409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }                                                                   \
173409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
174409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
175409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_ST(sb, stb, uint8_t)
176409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_ST(sw, stl, uint32_t)
177409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifdef TARGET_MIPS64
178409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_ST(sd, stq, uint64_t)
179409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
180409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#undef HELPER_ST
181409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
182409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallitarget_ulong helper_clo (target_ulong arg1)
183409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
184409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return clo32(arg1);
185409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
186409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
187409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallitarget_ulong helper_clz (target_ulong arg1)
188409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
189409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return clz32(arg1);
190409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
191409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
192409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if defined(TARGET_MIPS64)
193409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallitarget_ulong helper_dclo (target_ulong arg1)
194409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
195409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return clo64(arg1);
196409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
197409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
198409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallitarget_ulong helper_dclz (target_ulong arg1)
199409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
200409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return clz64(arg1);
201409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
202409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif /* TARGET_MIPS64 */
203409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
204409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* 64 bits arithmetic for 32 bits hosts */
2055c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnerstatic inline uint64_t get_HILO(CPUMIPSState *env)
206409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
207409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)(env->active_tc.HI[0]) << 32) | (uint32_t)env->active_tc.LO[0];
208409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
209409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2105c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnerstatic inline void set_HILO (CPUMIPSState *env, uint64_t HILO)
211409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
212409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.LO[0] = (int32_t)HILO;
213409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.HI[0] = (int32_t)(HILO >> 32);
214409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
215409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2165c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnerstatic inline void set_HIT0_LO (CPUMIPSState *env, target_ulong arg1, uint64_t HILO)
217409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
218409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
219409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    arg1 = env->active_tc.HI[0] = (int32_t)(HILO >> 32);
220409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
221409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2225c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnerstatic inline void set_HI_LOT0 (CPUMIPSState *env, target_ulong arg1, uint64_t HILO)
223409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
224409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    arg1 = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
225409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.HI[0] = (int32_t)(HILO >> 32);
226409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
227409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
228409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* Multiplication variants of the vr54xx. */
2295c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_muls(CPUMIPSState *env, target_ulong arg1,
2305c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                         target_ulong arg2)
231409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2325c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HI_LOT0(env, arg1, 0 - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
233409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
234409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
235409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
236409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2375c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1,
2385c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                          target_ulong arg2)
239409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2405c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HI_LOT0(env, arg1, 0 - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
241409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
242409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
243409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
244409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2455c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_macc(CPUMIPSState *env, target_ulong arg1,
2465c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                         target_ulong arg2)
247409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2485c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HI_LOT0(env, arg1, ((int64_t)get_HILO(env)) + ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
249409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
250409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
251409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
252409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2535c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1,
2545c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                           target_ulong arg2)
255409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2565c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HIT0_LO(env, arg1, ((int64_t)get_HILO(env)) + ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
257409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
258409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
259409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
260409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2615c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1,
2625c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                          target_ulong arg2)
263409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2645c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HI_LOT0(env, arg1, ((uint64_t)get_HILO(env)) + ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
265409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
266409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
267409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
268409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2695c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1,
2705c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                            target_ulong arg2)
271409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2725c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HIT0_LO(env, arg1, ((uint64_t)get_HILO(env)) + ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
273409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
274409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
275409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
276409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2775c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_msac(CPUMIPSState *env, target_ulong arg1,
2785c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                         target_ulong arg2)
279409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2805c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HI_LOT0(env, arg1, ((int64_t)get_HILO(env)) - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
281409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
282409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
283409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
284409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2855c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1,
2865c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                           target_ulong arg2)
287409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2885c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HIT0_LO(env, arg1, ((int64_t)get_HILO(env)) - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
289409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
290409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
291409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
292409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2935c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1,
2945c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                          target_ulong arg2)
295409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2965c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HI_LOT0(env, arg1, ((uint64_t)get_HILO(env)) - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
297409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
298409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
299409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
300409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3015c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1,
3025c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                            target_ulong arg2)
303409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3045c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HIT0_LO(env, arg1, ((uint64_t)get_HILO(env)) - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
305409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
306409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
307409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
308409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3095c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1,
3105c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                          target_ulong arg2)
311409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3125c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HIT0_LO(env, arg1, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
313409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
314409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
315409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
316409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3175c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1,
3185c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                           target_ulong arg2)
319409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3205c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HIT0_LO(env, arg1, (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
321409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
322409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
323409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
324409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3255c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1,
3265c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                           target_ulong arg2)
327409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3285c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HIT0_LO(env, arg1, 0 - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
329409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
330409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
331409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
332409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3335c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnertarget_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1,
3345c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner                            target_ulong arg2)
335409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3365c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turner    set_HIT0_LO(env, arg1, 0 - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
337409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
338409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
339409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
340409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
341409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifdef TARGET_MIPS64
3425c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnervoid helper_dmult (CPUMIPSState *env, target_ulong arg1, target_ulong arg2)
343409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
344409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    muls64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), arg1, arg2);
345409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
346409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3475c5a6e13ddb15cd1178071c60f0f22d265819021David 'Digit' Turnervoid helper_dmultu (CPUMIPSState *env, target_ulong arg1, target_ulong arg2)
348409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
349409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    mulu64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), arg1, arg2);
350409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
351409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
352409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
353409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifndef CONFIG_USER_ONLY
354409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3556cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turnerstatic inline hwaddr do_translate_address(CPUMIPSState *env,
3566cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner                                                      target_ulong address,
3576cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner                                                      int rw)
358409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
359bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turner    hwaddr lladdr;
360409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3616cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner    lladdr = cpu_mips_translate_address(env, address, rw);
362409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
363fa32c32d65a3082d4e06a1ba0e48eb40be27e7e0Chris Dearman    if (lladdr == (hwaddr)-1LL) {
3646cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner        cpu_loop_exit(env);
365409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    } else {
366409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return lladdr;
367409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
368409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
369409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
370409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define HELPER_LD_ATOMIC(name, insn)                                          \
3716cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turnertarget_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx)  \
372409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                             \
3736cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner    env->lladdr = do_translate_address(env, arg, 0);                        \
374cd35ed2793febb8f8fa19ad4e0052dba915d7c88David 'Digit' Turner    /* NOTE(digit): Use of 'cpu_single_env' works around compiler bug! */     \
3756cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner    cpu_single_env->llval = do_##insn(env, arg, mem_idx);                    \
3766cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner    return env->llval;                                                       \
377409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
378409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_LD_ATOMIC(ll, lw)
379409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifdef TARGET_MIPS64
380409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_LD_ATOMIC(lld, ld)
381409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
382409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#undef HELPER_LD_ATOMIC
383409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
384409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask)                      \
3856cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turnertarget_ulong helper_##name(CPUMIPSState *env, target_ulong arg1,              \
386cd35ed2793febb8f8fa19ad4e0052dba915d7c88David 'Digit' Turner                           target_ulong arg2, int mem_idx)                    \
387409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                             \
388409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_long tmp;                                                          \
389409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                              \
390409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (arg2 & almask) {                                                      \
391409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->CP0_BadVAddr = arg2;                                             \
3926cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner        helper_raise_exception(env, EXCP_AdES);                               \
393409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }                                                                         \
3946cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner    if (do_translate_address(env, arg2, 1) == env->lladdr) {                  \
3956cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner        tmp = do_##ld_insn(env, arg2, mem_idx);                               \
396409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (tmp == env->llval) {                                              \
3976cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turner            do_##st_insn(env, arg2, arg1, mem_idx);                           \
398409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            return 1;                                                         \
399409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        }                                                                     \
400409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }                                                                         \
401409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return 0;                                                                 \
402409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
403409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_ST_ATOMIC(sc, lw, sw, 0x3)
404409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifdef TARGET_MIPS64
405409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliHELPER_ST_ATOMIC(scd, ld, sd, 0x7)
406409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
407409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#undef HELPER_ST_ATOMIC
408409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
409409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
410409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifdef TARGET_WORDS_BIGENDIAN
411409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define GET_LMASK(v) ((v) & 3)
412409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define GET_OFFSET(addr, offset) (addr + (offset))
413409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#else
414409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define GET_LMASK(v) (((v) & 3) ^ 3)
415409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define GET_OFFSET(addr, offset) (addr - (offset))
416409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
417409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
418d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnertarget_ulong helper_lwl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
419d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                        int mem_idx)
420409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
421409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong tmp;
422409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
423d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    tmp = do_lbu(env, arg2, mem_idx);
424409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);
425409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
426409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) <= 2) {
427d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);
428409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);
429409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
430409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
431409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) <= 1) {
432d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);
433409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);
434409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
435409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
436409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) == 0) {
437d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);
438409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFF00) | tmp;
439409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
440409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return (int32_t)arg1;
441409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
442409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
443d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnertarget_ulong helper_lwr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
444d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                        int mem_idx)
445409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
446409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong tmp;
447409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
448d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    tmp = do_lbu(env, arg2, mem_idx);
449409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    arg1 = (arg1 & 0xFFFFFF00) | tmp;
450409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
451409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) >= 1) {
452d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -1), mem_idx);
453409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);
454409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
455409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
456409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) >= 2) {
457d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -2), mem_idx);
458409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);
459409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
460409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
461409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) == 3) {
462d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -3), mem_idx);
463409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);
464409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
465409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return (int32_t)arg1;
466409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
467409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
468d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnervoid helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
469d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                int mem_idx)
470409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
471d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    do_sb(env, arg2, (uint8_t)(arg1 >> 24), mem_idx);
472409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
473409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) <= 2)
474d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16), mem_idx);
475409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
476409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) <= 1)
477d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8), mem_idx);
478409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
479409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) == 0)
480d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)arg1, mem_idx);
481409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
482409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
483d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnervoid helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
484d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                int mem_idx)
485409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
486d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    do_sb(env, arg2, (uint8_t)arg1, mem_idx);
487409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
488409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) >= 1)
489d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
490409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
491409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) >= 2)
492d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
493409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
494409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK(arg2) == 3)
495d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
496409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
497409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
498409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if defined(TARGET_MIPS64)
499409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* "half" load and stores.  We must do the memory access inline,
500409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli   or fault handling won't work.  */
501409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
502409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifdef TARGET_WORDS_BIGENDIAN
503409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define GET_LMASK64(v) ((v) & 7)
504409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#else
505409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define GET_LMASK64(v) (((v) & 7) ^ 7)
506409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
507409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
508d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnertarget_ulong helper_ldl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
509d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                        int mem_idx)
510409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
511409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t tmp;
512409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
513d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    tmp = do_lbu(env, arg2, mem_idx);
514409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    arg1 = (arg1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
515409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
516409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 6) {
517d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);
518409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
519409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
520409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
521409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 5) {
522d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);
523409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
524409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
525409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
526409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 4) {
527d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);
528409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
529409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
530409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
531409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 3) {
532409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        tmp = do_lbu(GET_OFFSET(arg2, 4), mem_idx);
533409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
534409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
535409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
536409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 2) {
537d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, 5), mem_idx);
538409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
539409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
540409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
541409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 1) {
542d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, 6), mem_idx);
543409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
544409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
545409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
546409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) == 0) {
547d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, 7), mem_idx);
548409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
549409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
550409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
551409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
552409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
553409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
554d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnertarget_ulong helper_ldr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
555d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                        int mem_idx)
556409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
557409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t tmp;
558409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
559d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    tmp = do_lbu(env, arg2, mem_idx);
560409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    arg1 = (arg1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
561409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
562409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 1) {
563d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -1), mem_idx);
564409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFFFFFFFF00FFULL) | (tmp  << 8);
565409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
566409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
567409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 2) {
568d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -2), mem_idx);
569409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
570409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
571409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
572409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 3) {
573d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -3), mem_idx);
574409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
575409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
576409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
577409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 4) {
578d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -4), mem_idx);
579409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
580409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
581409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
582409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 5) {
583d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -5), mem_idx);
584409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
585409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
586409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
587409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 6) {
588d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -6), mem_idx);
589409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
590409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
591409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
592409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) == 7) {
593d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        tmp = do_lbu(env, GET_OFFSET(arg2, -7), mem_idx);
594409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (arg1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
595409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
596409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
597409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
598409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
599409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
600d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnervoid helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
601d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                 int mem_idx)
602409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
603d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    do_sb(env, arg2, (uint8_t)(arg1 >> 56), mem_idx);
604409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
605409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 6)
606d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48), mem_idx);
607409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
608409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 5)
609d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40), mem_idx);
610409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
611409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 4)
612d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32), mem_idx);
613409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
614409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 3)
615d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24), mem_idx);
616409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
617409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 2)
618d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16), mem_idx);
619409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
620409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 1)
621d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8), mem_idx);
622409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
623409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) <= 0)
624d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, 7), (uint8_t)arg1, mem_idx);
625409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
626409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
627d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turnervoid helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
628d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner                 int mem_idx)
629409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
630d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner    do_sb(env, arg2, (uint8_t)arg1, mem_idx);
631409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
632409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 1)
633d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
634409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
635409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 2)
636d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
637409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
638409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 3)
639d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
640409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
641409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 4)
642d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32), mem_idx);
643409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
644409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 5)
645d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40), mem_idx);
646409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
647409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) >= 6)
648d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48), mem_idx);
649409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
650409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_LMASK64(arg2) == 7)
651d62e538a5a9627bb1306ba14130699aaba9b585fDavid 'Digit' Turner        do_sb(env, GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56), mem_idx);
652409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
653409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif /* TARGET_MIPS64 */
654409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
655409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifndef CONFIG_USER_ONLY
656c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner/* tc should point to an int with the value of the global TC index.
657c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner   This function will transform it into a local index within the
658c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner   returned CPUState.
659c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner
660c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner   FIXME: This code assumes that all VPEs have the same number of TCs,
661c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner          which depends on runtime setup. Can probably be fixed by
66206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner          walking the list of CPUMIPSStates.  */
66306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnerstatic CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
664c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner{
6656657678c3d86395084f6a699e73614195f06c445David 'Digit' Turner    int vpe_idx, nr_threads = ENV_GET_CPU(env)->nr_threads;
666c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    int tc_idx = *tc;
667c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner
668c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))) {
669c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        /* Not allowed to address other CPUs.  */
670c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        *tc = env->current_tc;
671c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return env;
672c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    }
673c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner
674c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    vpe_idx = tc_idx / nr_threads;
675c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    *tc = tc_idx % nr_threads;
676bf7a22f3a6c38d359d2e933dec4706d1c7375f0aDavid 'Digit' Turner    CPUState *other = qemu_get_cpu(vpe_idx);
677bf7a22f3a6c38d359d2e933dec4706d1c7375f0aDavid 'Digit' Turner    return other ? other->env_ptr : env;
678c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner}
679c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner
680811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner/* The per VPE CP0_Status register shares some fields with the per TC
681811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner   CP0_TCStatus registers. These fields are wired to the same registers,
682811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner   so changes to either of them should be reflected on both registers.
683811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
684811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner   Also, EntryHi shares the bottom 8 bit ASID with TCStauts.
685811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
686811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner   These helper call synchronizes the regs for a given cpu.  */
687811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
688811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner/* Called for updates to CP0_Status.  */
68906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnerstatic void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc)
690811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner{
691811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    int32_t tcstatus, *tcst;
692811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    uint32_t v = cpu->CP0_Status;
693811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    uint32_t cu, mx, asid, ksu;
694811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    uint32_t mask = ((1 << CP0TCSt_TCU3)
695811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (1 << CP0TCSt_TCU2)
696811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (1 << CP0TCSt_TCU1)
697811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (1 << CP0TCSt_TCU0)
698811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (1 << CP0TCSt_TMX)
699811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (3 << CP0TCSt_TKSU)
700811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (0xff << CP0TCSt_TASID));
701811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
702811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    cu = (v >> CP0St_CU0) & 0xf;
703811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    mx = (v >> CP0St_MX) & 0x1;
704811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    ksu = (v >> CP0St_KSU) & 0x3;
705811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    asid = env->CP0_EntryHi & 0xff;
706811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
707811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    tcstatus = cu << CP0TCSt_TCU0;
708811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    tcstatus |= mx << CP0TCSt_TMX;
709811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    tcstatus |= ksu << CP0TCSt_TKSU;
710811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    tcstatus |= asid;
711811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
712811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    if (tc == cpu->current_tc) {
713811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner        tcst = &cpu->active_tc.CP0_TCStatus;
714811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    } else {
715811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner        tcst = &cpu->tcs[tc].CP0_TCStatus;
716811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    }
717811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
718811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    *tcst &= ~mask;
719811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    *tcst |= tcstatus;
720811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    compute_hflags(cpu);
721811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner}
722811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
723811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner/* Called for updates to CP0_TCStatus.  */
72406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnerstatic void sync_c0_tcstatus(CPUMIPSState *cpu, int tc,
72506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner                             target_ulong v)
726811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner{
727811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    uint32_t status;
728811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    uint32_t tcu, tmx, tasid, tksu;
729811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    uint32_t mask = ((1 << CP0St_CU3)
730811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (1 << CP0St_CU2)
731811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (1 << CP0St_CU1)
732811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (1 << CP0St_CU0)
733811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (1 << CP0St_MX)
734811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner                       | (3 << CP0St_KSU));
735811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
736811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    tcu = (v >> CP0TCSt_TCU0) & 0xf;
737811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    tmx = (v >> CP0TCSt_TMX) & 0x1;
738811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    tasid = v & 0xff;
739811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    tksu = (v >> CP0TCSt_TKSU) & 0x3;
740811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
741811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    status = tcu << CP0St_CU0;
742811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    status |= tmx << CP0St_MX;
743811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    status |= tksu << CP0St_KSU;
744811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
745811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    cpu->CP0_Status &= ~mask;
746811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    cpu->CP0_Status |= status;
747811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
748811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    /* Sync the TASID with EntryHi.  */
749811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    cpu->CP0_EntryHi &= ~0xff;
750811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    cpu->CP0_EntryHi = tasid;
751811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
752811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    compute_hflags(cpu);
753811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner}
754811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
755811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner/* Called for updates to CP0_EntryHi.  */
756811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turnerstatic void sync_c0_entryhi(CPUMIPSState *cpu, int tc)
757811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner{
758811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    int32_t *tcst;
759811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    uint32_t asid, v = cpu->CP0_EntryHi;
760811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
761811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    asid = v & 0xff;
762811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
763811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    if (tc == cpu->current_tc) {
764811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner        tcst = &cpu->active_tc.CP0_TCStatus;
765811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    } else {
766811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner        tcst = &cpu->tcs[tc].CP0_TCStatus;
767811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    }
768811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
769811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    *tcst &= ~0xff;
770811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    *tcst |= asid;
771811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner}
772811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
773409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* CP0 helpers */
77406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_mvpcontrol(CPUMIPSState *env)
775409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
776409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->mvp->CP0_MVPControl;
777409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
778409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
77906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_mvpconf0(CPUMIPSState *env)
780409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
781409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->mvp->CP0_MVPConf0;
782409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
783409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
78406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_mvpconf1(CPUMIPSState *env)
785409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
786409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->mvp->CP0_MVPConf1;
787409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
788409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
78906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_random(CPUMIPSState *env)
790409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
791409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return (int32_t)cpu_mips_get_random(env);
792409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
793409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
79406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_tcstatus(CPUMIPSState *env)
795409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
796409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCStatus;
797409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
798409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
79906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_tcstatus(CPUMIPSState *env)
800409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
801409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
80206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
803409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
804c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
805c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.CP0_TCStatus;
806409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
807c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].CP0_TCStatus;
808409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
809409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
81006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_tcbind(CPUMIPSState *env)
811409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
812409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCBind;
813409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
814409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
81506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_tcbind(CPUMIPSState *env)
816409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
817409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
81806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
819409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
820c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
821c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.CP0_TCBind;
822409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
823c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].CP0_TCBind;
824409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
825409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
82606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_tcrestart(CPUMIPSState *env)
827409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
828409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.PC;
829409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
830409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
83106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_tcrestart(CPUMIPSState *env)
832409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
833409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
83406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
835409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
836c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
837c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.PC;
838409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
839c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].PC;
840409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
841409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
84206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_tchalt(CPUMIPSState *env)
843409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
844409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCHalt;
845409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
846409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
84706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_tchalt(CPUMIPSState *env)
848409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
849409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
85006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
851409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
852c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
853c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.CP0_TCHalt;
854409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
855c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].CP0_TCHalt;
856409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
857409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
85806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_tccontext(CPUMIPSState *env)
859409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
860409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCContext;
861409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
862409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
86306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_tccontext(CPUMIPSState *env)
864409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
865409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
86606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
867409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
868c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
869c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.CP0_TCContext;
870409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
871c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].CP0_TCContext;
872409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
873409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
87406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_tcschedule(CPUMIPSState *env)
875409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
876409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCSchedule;
877409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
878409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
87906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_tcschedule(CPUMIPSState *env)
880409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
881409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
88206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
883409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
884c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
885c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.CP0_TCSchedule;
886409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
887c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].CP0_TCSchedule;
888409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
889409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
89006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_tcschefback(CPUMIPSState *env)
891409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
892409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCScheFBack;
893409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
894409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
89506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_tcschefback(CPUMIPSState *env)
896409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
897409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
89806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
899409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
900c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
901c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.CP0_TCScheFBack;
902409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
903c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].CP0_TCScheFBack;
904409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
905409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
90606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_count(CPUMIPSState *env)
907409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
908409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return (int32_t)cpu_mips_get_count(env);
909409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
910409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
91106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_entryhi(CPUMIPSState *env)
912409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
913409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
91406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
915409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
916811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    return other->CP0_EntryHi;
917409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
918409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
91906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_status(CPUMIPSState *env)
920409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
921409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
92206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
923409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
924811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    return other->CP0_Status;
925409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
926409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
92706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_lladdr(CPUMIPSState *env)
928409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
929409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return (int32_t)(env->lladdr >> env->CP0_LLAddr_shift);
930409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
931409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
93206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_watchlo(CPUMIPSState *env, uint32_t sel)
933409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
934409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return (int32_t)env->CP0_WatchLo[sel];
935409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
936409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
93706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_watchhi(CPUMIPSState *env, uint32_t sel)
938409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
939409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->CP0_WatchHi[sel];
940409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
941409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
94206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mfc0_debug(CPUMIPSState *env)
943409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
944409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong t0 = env->CP0_Debug;
945409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (env->hflags & MIPS_HFLAG_DM)
946409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        t0 |= 1 << CP0DB_DM;
947409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
948409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return t0;
949409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
950409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
95106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_mftc0_debug(CPUMIPSState *env)
952409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
953409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
954409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int32_t tcstatus;
95506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
956409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
957c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
958c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        tcstatus = other->active_tc.CP0_Debug_tcstatus;
959409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
960c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        tcstatus = other->tcs[other_tc].CP0_Debug_tcstatus;
961409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
962409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* XXX: Might be wrong, check with EJTAG spec. */
963c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    return (other->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
964409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            (tcstatus & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
965409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
966409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
967409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if defined(TARGET_MIPS64)
96806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_dmfc0_tcrestart(CPUMIPSState *env)
969409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
970409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.PC;
971409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
972409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
97306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_dmfc0_tchalt(CPUMIPSState *env)
974409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
975409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCHalt;
976409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
977409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
97806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_dmfc0_tccontext(CPUMIPSState *env)
979409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
980409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCContext;
981409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
982409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
98306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_dmfc0_tcschedule(CPUMIPSState *env)
984409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
985409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCSchedule;
986409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
987409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
98806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_dmfc0_tcschefback(CPUMIPSState *env)
989409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
990409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->active_tc.CP0_TCScheFBack;
991409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
992409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
99306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_dmfc0_lladdr(CPUMIPSState *env)
994409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
995409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->lladdr >> env->CP0_LLAddr_shift;
996409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
997409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
99806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnertarget_ulong helper_dmfc0_watchlo(CPUMIPSState *env, uint32_t sel)
999409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1000409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->CP0_WatchLo[sel];
1001409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1002409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif /* TARGET_MIPS64 */
1003409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
100406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_index(CPUMIPSState *env, target_ulong arg1)
1005409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1006409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int num = 1;
1007409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    unsigned int tmp = env->tlb->nb_tlb;
1008409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1009409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    do {
1010409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        tmp >>= 1;
1011409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        num <<= 1;
1012409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    } while (tmp);
1013409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Index = (env->CP0_Index & 0x80000000) | (arg1 & (num - 1));
1014409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1015409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
101606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_mvpcontrol(CPUMIPSState *env, target_ulong arg1)
1017409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1018409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask = 0;
1019409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t newval;
1020409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1021409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))
1022409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) |
1023409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                (1 << CP0MVPCo_EVP);
1024409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1025409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        mask |= (1 << CP0MVPCo_STLB);
1026409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    newval = (env->mvp->CP0_MVPControl & ~mask) | (arg1 & mask);
1027409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1028409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO: Enable/disable shared TLB, enable/disable VPEs.
1029409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1030409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->mvp->CP0_MVPControl = newval;
1031409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1032409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
103306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_vpecontrol(CPUMIPSState *env, target_ulong arg1)
1034409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1035409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask;
1036409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t newval;
1037409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1038409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
1039409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli           (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
1040409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    newval = (env->CP0_VPEControl & ~mask) | (arg1 & mask);
1041409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1042409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* Yield scheduler intercept not implemented. */
1043409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* Gating storage scheduler intercept not implemented. */
1044409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1045409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO: Enable/disable TCs.
1046409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1047409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_VPEControl = newval;
1048409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1049409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
105006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_vpeconf0(CPUMIPSState *env, target_ulong arg1)
1051409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1052409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask = 0;
1053409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t newval;
1054409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1055409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) {
1056409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))
1057409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            mask |= (0xff << CP0VPEC0_XTC);
1058409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
1059409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1060409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    newval = (env->CP0_VPEConf0 & ~mask) | (arg1 & mask);
1061409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1062409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO: TC exclusive handling due to ERL/EXL.
1063409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1064409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_VPEConf0 = newval;
1065409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1066409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
106706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_vpeconf1(CPUMIPSState *env, target_ulong arg1)
1068409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1069409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask = 0;
1070409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t newval;
1071409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1072409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1073409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) |
1074409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                (0xff << CP0VPEC1_NCP1);
1075409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    newval = (env->CP0_VPEConf1 & ~mask) | (arg1 & mask);
1076409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1077409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* UDI not implemented. */
1078409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* CP2 not implemented. */
1079409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1080409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO: Handle FPU (CP1) binding.
1081409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1082409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_VPEConf1 = newval;
1083409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1084409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
108506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_yqmask(CPUMIPSState *env, target_ulong arg1)
1086409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1087409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* Yield qualifier inputs not implemented. */
1088409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_YQMask = 0x00000000;
1089409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1090409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
109106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_vpeopt(CPUMIPSState *env, target_ulong arg1)
1092409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1093409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_VPEOpt = arg1 & 0x0000ffff;
1094409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1095409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
109606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_entrylo0(CPUMIPSState *env, target_ulong arg1)
1097409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1098409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* Large physaddr (PABITS) not implemented */
1099409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* 1k pages not implemented */
1100409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_EntryLo0 = arg1 & 0x3FFFFFFF;
1101409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1102409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
110306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
1104409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1105409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask = env->CP0_TCStatus_rw_bitmask;
1106409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t newval;
1107409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1108409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    newval = (env->active_tc.CP0_TCStatus & ~mask) | (arg1 & mask);
1109409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1110409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.CP0_TCStatus = newval;
1111811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    sync_c0_tcstatus(env, env->current_tc, newval);
1112409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1113409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
111406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
1115409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1116409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
111706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1118409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1119c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1120c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.CP0_TCStatus = arg1;
1121409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1122c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].CP0_TCStatus = arg1;
1123811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    sync_c0_tcstatus(other, other_tc, arg1);
1124409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1125409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
112606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_tcbind(CPUMIPSState *env, target_ulong arg1)
1127409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1128409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask = (1 << CP0TCBd_TBE);
1129409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t newval;
1130409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1131409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1132409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        mask |= (1 << CP0TCBd_CurVPE);
1133409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    newval = (env->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
1134409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.CP0_TCBind = newval;
1135409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1136409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
113706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_tcbind(CPUMIPSState *env, target_ulong arg1)
1138409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1139409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1140409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask = (1 << CP0TCBd_TBE);
1141409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t newval;
114206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1143409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1144c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
1145409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        mask |= (1 << CP0TCBd_CurVPE);
1146c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc) {
1147c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        newval = (other->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
1148c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.CP0_TCBind = newval;
1149409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    } else {
1150c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        newval = (other->tcs[other_tc].CP0_TCBind & ~mask) | (arg1 & mask);
1151c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].CP0_TCBind = newval;
1152409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1153409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1154409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
115506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_tcrestart(CPUMIPSState *env, target_ulong arg1)
1156409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1157409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.PC = arg1;
1158409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
1159409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->lladdr = 0ULL;
1160409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* MIPS16 not implemented. */
1161409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1162409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
116306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_tcrestart(CPUMIPSState *env, target_ulong arg1)
1164409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1165409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
116606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1167409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1168c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc) {
1169c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.PC = arg1;
1170c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
1171c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->lladdr = 0ULL;
1172409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        /* MIPS16 not implemented. */
1173409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    } else {
1174c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].PC = arg1;
1175c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
1176c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->lladdr = 0ULL;
1177409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        /* MIPS16 not implemented. */
1178409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1179409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1180409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
118106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_tchalt(CPUMIPSState *env, target_ulong arg1)
1182409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1183409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.CP0_TCHalt = arg1 & 0x1;
1184409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1185409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO: Halt TC / Restart (if allocated+active) TC.
1186409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1187409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
118806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_tchalt(CPUMIPSState *env, target_ulong arg1)
1189409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1190409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
119106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1192409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1193409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO: Halt TC / Restart (if allocated+active) TC.
1194409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1195c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1196c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.CP0_TCHalt = arg1;
1197409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1198c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].CP0_TCHalt = arg1;
1199409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1200409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
120106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_tccontext(CPUMIPSState *env, target_ulong arg1)
1202409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1203409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.CP0_TCContext = arg1;
1204409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1205409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
120606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_tccontext(CPUMIPSState *env, target_ulong arg1)
1207409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1208409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
120906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1210409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1211c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1212c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.CP0_TCContext = arg1;
1213409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1214c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].CP0_TCContext = arg1;
1215409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1216409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
121706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_tcschedule(CPUMIPSState *env, target_ulong arg1)
1218409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1219409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.CP0_TCSchedule = arg1;
1220409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1221409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
122206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_tcschedule(CPUMIPSState *env, target_ulong arg1)
1223409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1224409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
122506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1226409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1227c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1228c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.CP0_TCSchedule = arg1;
1229409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1230c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].CP0_TCSchedule = arg1;
1231409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1232409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
123306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_tcschefback(CPUMIPSState *env, target_ulong arg1)
1234409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1235409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.CP0_TCScheFBack = arg1;
1236409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1237409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
123806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_tcschefback(CPUMIPSState *env, target_ulong arg1)
1239409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1240409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
124106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1242409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1243c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1244c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.CP0_TCScheFBack = arg1;
1245409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1246c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].CP0_TCScheFBack = arg1;
1247409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1248409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
124906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_entrylo1(CPUMIPSState *env, target_ulong arg1)
1250409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1251409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* Large physaddr (PABITS) not implemented */
1252409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* 1k pages not implemented */
1253409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_EntryLo1 = arg1 & 0x3FFFFFFF;
1254409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1255409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
125606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_context(CPUMIPSState *env, target_ulong arg1)
1257409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1258409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (arg1 & ~0x007FFFFF);
1259409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1260409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
126106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
1262409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1263409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* 1k pages not implemented */
1264409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_PageMask = arg1 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
1265409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1266409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
126706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
1268409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1269409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* SmartMIPS not implemented */
1270409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* Large physaddr (PABITS) not implemented */
1271409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* 1k pages not implemented */
1272409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_PageGrain = 0;
1273409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1274409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
127506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
1276409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1277409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Wired = arg1 % env->tlb->nb_tlb;
1278409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1279409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
128006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_srsconf0(CPUMIPSState *env, target_ulong arg1)
1281409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1282409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_SRSConf0 |= arg1 & env->CP0_SRSConf0_rw_bitmask;
1283409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1284409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
128506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_srsconf1(CPUMIPSState *env, target_ulong arg1)
1286409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1287409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_SRSConf1 |= arg1 & env->CP0_SRSConf1_rw_bitmask;
1288409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1289409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
129006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_srsconf2(CPUMIPSState *env, target_ulong arg1)
1291409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1292409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_SRSConf2 |= arg1 & env->CP0_SRSConf2_rw_bitmask;
1293409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1294409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
129506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_srsconf3(CPUMIPSState *env, target_ulong arg1)
1296409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1297409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_SRSConf3 |= arg1 & env->CP0_SRSConf3_rw_bitmask;
1298409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1299409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
130006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_srsconf4(CPUMIPSState *env, target_ulong arg1)
1301409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1302409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_SRSConf4 |= arg1 & env->CP0_SRSConf4_rw_bitmask;
1303409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1304409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
130506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1)
1306409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1307409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_HWREna = arg1 & 0x0000000F;
1308409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1309409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
131006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_count(CPUMIPSState *env, target_ulong arg1)
1311409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1312409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    cpu_mips_store_count(env, arg1);
1313409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1314409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
131506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
1316409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1317409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong old, val;
1318409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1319409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* 1k pages not implemented */
1320409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    val = arg1 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1321409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if defined(TARGET_MIPS64)
1322409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    val &= env->SEGMask;
1323409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
1324409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    old = env->CP0_EntryHi;
1325409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_EntryHi = val;
1326409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1327811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner        sync_c0_entryhi(env, env->current_tc);
1328409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1329409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* If the ASID changes, flush qemu's TLB.  */
1330409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if ((old & 0xFF) != (val & 0xFF))
1331409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        cpu_mips_tlb_flush(env, 1);
1332409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1333409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
133406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_entryhi(CPUMIPSState *env, target_ulong arg1)
1335409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1336409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
133706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1338409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1339811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    other->CP0_EntryHi = arg1;
1340811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    sync_c0_entryhi(other, other_tc);
1341409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1342409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
134306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_compare(CPUMIPSState *env, target_ulong arg1)
1344409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1345409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    cpu_mips_store_compare(env, arg1);
1346409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1347409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
134806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_status(CPUMIPSState *env, target_ulong arg1)
1349409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1350409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t val, old;
1351409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask = env->CP0_Status_rw_bitmask;
1352409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1353409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    val = arg1 & mask;
1354409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    old = env->CP0_Status;
1355409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Status = (env->CP0_Status & ~mask) | val;
1356811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
135706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner        sync_c0_status(env, env, env->current_tc);
1358811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    } else {
1359811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner        compute_hflags(env);
1360811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner    }
1361811b0299ba969b708c7c15b50ebe205b87877a08David 'Digit' Turner
1362409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
1363409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        qemu_log("Status %08x (%08x) => %08x (%08x) Cause %08x",
1364409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                old, old & env->CP0_Cause & CP0Ca_IP_mask,
1365409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                val, val & env->CP0_Cause & CP0Ca_IP_mask,
1366409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                env->CP0_Cause);
1367409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        switch (env->hflags & MIPS_HFLAG_KSU) {
1368409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        case MIPS_HFLAG_UM: qemu_log(", UM\n"); break;
1369409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        case MIPS_HFLAG_SM: qemu_log(", SM\n"); break;
1370409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        case MIPS_HFLAG_KM: qemu_log("\n"); break;
1371409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        default: cpu_abort(env, "Invalid MMU mode!\n"); break;
1372409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        }
1373409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1374409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    cpu_mips_update_irq(env);
1375409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1376409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
137706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_status(CPUMIPSState *env, target_ulong arg1)
1378409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1379409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
138006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1381409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1382c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    other->CP0_Status = arg1 & ~0xf1000018;
138306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    sync_c0_status(env, other, other_tc);
1384409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1385409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
138606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_intctl(CPUMIPSState *env, target_ulong arg1)
1387409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1388409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* vectored interrupts not implemented, no performance counters. */
1389409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (arg1 & 0x000002e0);
1390409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1391409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
139206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_srsctl(CPUMIPSState *env, target_ulong arg1)
1393409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1394409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
1395409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (arg1 & mask);
1396409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1397409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
139806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_cause(CPUMIPSState *env, target_ulong arg1)
1399409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1400409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t mask = 0x00C00300;
1401409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t old = env->CP0_Cause;
1402409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1403409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (env->insn_flags & ISA_MIPS32R2)
1404409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        mask |= 1 << CP0Ca_DC;
1405409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1406409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Cause = (env->CP0_Cause & ~mask) | (arg1 & mask);
1407409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1408409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1409409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (env->CP0_Cause & (1 << CP0Ca_DC))
1410409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            cpu_mips_stop_count(env);
1411409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        else
1412409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            cpu_mips_start_count(env);
1413409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1414409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1415409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* Handle the software interrupt as an hardware one, as they
1416409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli       are very similar */
1417409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (arg1 & CP0Ca_IP_mask) {
1418409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        cpu_mips_update_irq(env);
1419409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1420409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1421409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
142206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
1423409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1424409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* vectored interrupts not implemented */
1425409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* Multi-CPU not implemented */
1426409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_EBase = 0x80000000 | (arg1 & 0x3FFFF000);
1427409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1428409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
142906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_config0(CPUMIPSState *env, target_ulong arg1)
1430409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1431409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (arg1 & 0x00000007);
1432409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1433409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
143406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_config2(CPUMIPSState *env, target_ulong arg1)
1435409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1436409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* tertiary/secondary caches not implemented */
1437409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
1438409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1439409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
144006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_lladdr(CPUMIPSState *env, target_ulong arg1)
1441409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1442409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_long mask = env->CP0_LLAddr_rw_bitmask;
1443409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    arg1 = arg1 << env->CP0_LLAddr_shift;
1444409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->lladdr = (env->lladdr & ~mask) | (arg1 & mask);
1445409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1446409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
144706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
1448409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1449409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* Watch exceptions for instructions, data loads, data stores
1450409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli       not implemented. */
1451409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_WatchLo[sel] = (arg1 & ~0x7);
1452409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1453409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
145406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
1455409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1456409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_WatchHi[sel] = (arg1 & 0x40FF0FF8);
1457409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & arg1 & 0x7);
1458409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1459409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
146006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_xcontext(CPUMIPSState *env, target_ulong arg1)
1461409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1462409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1463409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_XContext = (env->CP0_XContext & mask) | (arg1 & ~mask);
1464409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1465409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
146606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_framemask(CPUMIPSState *env, target_ulong arg1)
1467409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1468409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Framemask = arg1; /* XXX */
1469409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1470409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
147106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_debug(CPUMIPSState *env, target_ulong arg1)
1472409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1473409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (arg1 & 0x13300120);
1474409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (arg1 & (1 << CP0DB_DM))
1475409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->hflags |= MIPS_HFLAG_DM;
1476409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1477409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->hflags &= ~MIPS_HFLAG_DM;
1478409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1479409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
148006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mttc0_debug(CPUMIPSState *env, target_ulong arg1)
1481409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1482409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1483409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t val = arg1 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
148406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1485409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1486409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* XXX: Might be wrong, check with EJTAG spec. */
1487c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1488c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.CP0_Debug_tcstatus = val;
1489409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1490c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].CP0_Debug_tcstatus = val;
1491c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    other->CP0_Debug = (other->CP0_Debug &
1492c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner                     ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
1493409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                     (arg1 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
1494409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1495409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
149606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_performance0(CPUMIPSState *env, target_ulong arg1)
1497409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1498409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Performance0 = arg1 & 0x000007ff;
1499409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1500409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
150106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_taglo(CPUMIPSState *env, target_ulong arg1)
1502409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1503409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_TagLo = arg1 & 0xFFFFFCF6;
1504409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1505409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
150606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_datalo(CPUMIPSState *env, target_ulong arg1)
1507409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1508409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_DataLo = arg1; /* XXX */
1509409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1510409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
151106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_taghi(CPUMIPSState *env, target_ulong arg1)
1512409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1513409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_TagHi = arg1; /* XXX */
1514409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1515409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
151606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turnervoid helper_mtc0_datahi(CPUMIPSState *env, target_ulong arg1)
1517409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1518409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_DataHi = arg1; /* XXX */
1519409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1520409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1521409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* MIPS MT functions */
152226efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_mftgpr(CPUMIPSState *env, uint32_t sel)
1523409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1524409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
152506978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1526409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1527c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1528c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.gpr[sel];
1529409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1530c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].gpr[sel];
1531409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1532409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
153326efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_mftlo(CPUMIPSState *env, uint32_t sel)
1534409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1535409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
153606978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1537409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1538c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1539c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.LO[sel];
1540409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1541c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].LO[sel];
1542409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1543409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
154426efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_mfthi(CPUMIPSState *env, uint32_t sel)
1545409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1546409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
154706978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1548409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1549c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1550c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.HI[sel];
1551409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1552c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].HI[sel];
1553409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1554409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
155526efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_mftacx(CPUMIPSState *env, uint32_t sel)
1556409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1557409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
155806978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1559409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1560c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1561c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.ACX[sel];
1562409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1563c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].ACX[sel];
1564409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1565409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
156626efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_mftdsp(CPUMIPSState *env)
1567409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1568409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
156906978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1570409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1571c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1572c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->active_tc.DSPControl;
1573409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1574c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        return other->tcs[other_tc].DSPControl;
1575409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1576409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
157726efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnervoid helper_mttgpr(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
1578409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1579409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
158006978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1581409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1582c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1583c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.gpr[sel] = arg1;
1584409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1585c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].gpr[sel] = arg1;
1586409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1587409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
158826efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnervoid helper_mttlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
1589409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1590409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
159106978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1592409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1593c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1594c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.LO[sel] = arg1;
1595409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1596c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].LO[sel] = arg1;
1597409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1598409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
159926efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnervoid helper_mtthi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
1600409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1601409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
160206978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1603409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1604c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1605c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.HI[sel] = arg1;
1606409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1607c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].HI[sel] = arg1;
1608409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1609409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
161026efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnervoid helper_mttacx(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
1611409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1612409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
161306978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1614409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1615c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1616c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.ACX[sel] = arg1;
1617409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1618c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].ACX[sel] = arg1;
1619409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1620409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
162126efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnervoid helper_mttdsp(CPUMIPSState *env, target_ulong arg1)
1622409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1623409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
162406978cc902013686f4443582e55361f0d86fbc2eDavid 'Digit' Turner    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
1625409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1626c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner    if (other_tc == other->current_tc)
1627c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->active_tc.DSPControl = arg1;
1628409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
1629c8ba4e8ec5a6b3ff95dcd7d2c61d88363e5699baDavid 'Digit' Turner        other->tcs[other_tc].DSPControl = arg1;
1630409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1631409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1632409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* MIPS MT functions */
163326efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_dmt(void)
1634409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1635409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO
163626efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turner     return 0;
1637409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1638409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
163926efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_emt(void)
1640409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1641409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO
164226efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turner    return 0;
1643409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1644409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
164526efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_dvpe(CPUMIPSState *env)
1646409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1647409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO
164826efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turner    return 0;
1649409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1650409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
165126efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_evpe(CPUMIPSState *env)
1652409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1653409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO
165426efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turner    return 0;
1655409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1656409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif /* !CONFIG_USER_ONLY */
1657409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1658409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallivoid helper_fork(target_ulong arg1, target_ulong arg2)
1659409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1660409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // arg1 = rt, arg2 = rs
1661409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    arg1 = 0;
1662409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    // TODO: store to TC register
1663409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1664409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
166526efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turnertarget_ulong helper_yield(CPUMIPSState *env, target_ulong arg)
1666409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
166726efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turner    target_long arg1 = arg;
166826efe758c079d8be435ec74470731237cd777c1dDavid 'Digit' Turner
1669409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (arg1 < 0) {
1670409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        /* No scheduling policy implemented. */
1671409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (arg1 != -2) {
1672409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) &&
1673409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                env->active_tc.CP0_TCStatus & (1 << CP0TCSt_DT)) {
1674409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1675409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
16766480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner                helper_raise_exception(env, EXCP_THREAD);
1677409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            }
1678409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        }
1679409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    } else if (arg1 == 0) {
1680409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (0 /* TODO: TC underflow */) {
1681409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
16826480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner            helper_raise_exception(env, EXCP_THREAD);
1683409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        } else {
1684409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            // TODO: Deallocate TC
1685409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        }
1686409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    } else if (arg1 > 0) {
1687409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        /* Yield qualifier inputs not implemented. */
1688409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
1689409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
16906480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_THREAD);
1691409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1692409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return env->CP0_YQMask;
1693409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1694409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1695409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifndef CONFIG_USER_ONLY
1696e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turnerstatic void inline r4k_invalidate_tlb_shadow (CPUMIPSState *env, int idx)
1697409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
169855ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    r4k_tlb_t *tlb;
169955ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    uint8_t ASID = env->CP0_EntryHi & 0xFF;
170055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman
170155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    tlb = &env->tlb->mmu.r4k.tlb[idx];
170255ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    /* The qemu TLB is flushed when the ASID changes, so no need to
170355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    flush these entries again.  */
170455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    if (tlb->G == 0 && tlb->ASID != ASID) {
170555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        return;
170655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    }
1707409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1708409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1709e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turnerstatic void inline r4k_invalidate_tlb (CPUMIPSState *env, int idx)
1710409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
171155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    r4k_tlb_t *tlb;
171255ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    target_ulong addr;
171355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    target_ulong end;
171455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    uint8_t ASID = env->CP0_EntryHi & 0xFF;
171555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    target_ulong mask;
171655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman
171755ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    tlb = &env->tlb->mmu.r4k.tlb[idx];
171855ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    /* The qemu TLB is flushed when the ASID changes, so no need to
171955ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    flush these entries again.  */
172055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    if (tlb->G == 0 && tlb->ASID != ASID) {
172155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        return;
1722409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
172355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman
172455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    /* 1k pages are not supported. */
172555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
172655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    if (tlb->V0) {
172755ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        addr = tlb->VPN & ~mask;
172855ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman#if defined(TARGET_MIPS64)
172955ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
173055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            addr |= 0x3FFFFF0000000000ULL;
173155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        }
173255ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman#endif
173355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        end = addr | (mask >> 1);
173455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        while (addr < end) {
173555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb_flush_page (env, addr);
173655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            addr += TARGET_PAGE_SIZE;
173755ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        }
173855ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    }
173955ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    if (tlb->V1) {
174055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
174155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman#if defined(TARGET_MIPS64)
174255ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
174355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            addr |= 0x3FFFFF0000000000ULL;
174455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        }
174555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman#endif
174655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        end = addr | mask;
174755ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        while (addr - 1 < end) {
174855ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb_flush_page (env, addr);
174955ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            addr += TARGET_PAGE_SIZE;
175055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        }
175155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    }
175255ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman}
175355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman
175455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman/* TLB management */
1755e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turnervoid cpu_mips_tlb_flush (CPUMIPSState *env, int flush_global)
175655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman{
175755ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    /* Flush qemu's TLB and discard all shadowed entries.  */
175855ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    tlb_flush (env, flush_global);
1759409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1760409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1761758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnerstatic void r4k_fill_tlb(CPUMIPSState *env, int idx)
1762409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1763409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    r4k_tlb_t *tlb;
1764409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1765409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
1766409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb = &env->tlb->mmu.r4k.tlb[idx];
1767409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
1768409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if defined(TARGET_MIPS64)
1769409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->VPN &= env->SEGMask;
1770409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif
1771409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->ASID = env->CP0_EntryHi & 0xFF;
1772409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->PageMask = env->CP0_PageMask;
1773409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
1774409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->V0 = (env->CP0_EntryLo0 & 2) != 0;
1775409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->D0 = (env->CP0_EntryLo0 & 4) != 0;
1776409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->C0 = (env->CP0_EntryLo0 >> 3) & 0x7;
1777409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->PFN[0] = (env->CP0_EntryLo0 >> 6) << 12;
1778409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->V1 = (env->CP0_EntryLo1 & 2) != 0;
1779409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->D1 = (env->CP0_EntryLo1 & 4) != 0;
1780409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->C1 = (env->CP0_EntryLo1 >> 3) & 0x7;
1781409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    tlb->PFN[1] = (env->CP0_EntryLo1 >> 6) << 12;
1782409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1783409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1784758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnervoid r4k_helper_ptw_tlbrefill(CPUMIPSState *env)
178555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman{
178655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman   /* Do TLB load on behalf of Page Table Walk */
178755ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    int r = cpu_mips_get_random(env);
178855ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    r4k_invalidate_tlb_shadow(env, r);
1789758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turner    r4k_fill_tlb(env, r);
179055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman}
179155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman
1792758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnervoid r4k_helper_tlbwi (CPUMIPSState *env)
1793409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
179455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    r4k_tlb_t *tlb;
179555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    target_ulong tag;
179655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    target_ulong VPN;
179755ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    target_ulong mask;
1798409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
179955ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    /* If tlbwi is trying to upgrading access permissions on current entry,
180055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman     * we do not need to flush tlb hash table.
180155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman     */
180255ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    tlb = &env->tlb->mmu.r4k.tlb[env->CP0_Index % env->tlb->nb_tlb];
180355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
180455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    tag = env->CP0_EntryHi & ~mask;
180555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    VPN = tlb->VPN & ~mask;
180655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    if (VPN == tag)
180755ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    {
180855ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        if (tlb->ASID == (env->CP0_EntryHi & 0xFF))
180955ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        {
181055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb->V0 = (env->CP0_EntryLo0 & 2) != 0;
181155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb->D0 = (env->CP0_EntryLo0 & 4) != 0;
181255ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb->C0 = (env->CP0_EntryLo0 >> 3) & 0x7;
181355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb->PFN[0] = (env->CP0_EntryLo0 >> 6) << 12;
181455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb->V1 = (env->CP0_EntryLo1 & 2) != 0;
181555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb->D1 = (env->CP0_EntryLo1 & 4) != 0;
181655ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb->C1 = (env->CP0_EntryLo1 >> 3) & 0x7;
181755ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            tlb->PFN[1] = (env->CP0_EntryLo1 >> 6) << 12;
181855ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman            return;
181955ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        }
182055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    }
1821409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
182255ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    /*flush all the tlb cache */
182355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    cpu_mips_tlb_flush (env, 1);
1824409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
182555ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    r4k_invalidate_tlb(env, env->CP0_Index % env->tlb->nb_tlb);
1826758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turner    r4k_fill_tlb(env, env->CP0_Index % env->tlb->nb_tlb);
1827409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1828409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1829758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnervoid r4k_helper_tlbwr (CPUMIPSState *env)
1830409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1831409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int r = cpu_mips_get_random(env);
1832409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
183355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    r4k_invalidate_tlb_shadow(env, r);
1834758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turner    r4k_fill_tlb(env, r);
1835409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1836409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1837758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnervoid r4k_helper_tlbp(CPUMIPSState *env)
1838409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1839409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    r4k_tlb_t *tlb;
1840409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong mask;
1841409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong tag;
1842409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong VPN;
1843409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint8_t ASID;
1844409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int i;
1845409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1846409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    ASID = env->CP0_EntryHi & 0xFF;
1847409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    for (i = 0; i < env->tlb->nb_tlb; i++) {
1848409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        tlb = &env->tlb->mmu.r4k.tlb[i];
1849409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        /* 1k pages are not supported. */
1850409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        mask = tlb->PageMask | ~(TARGET_PAGE_MASK << 1);
1851409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        tag = env->CP0_EntryHi & ~mask;
1852409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        VPN = tlb->VPN & ~mask;
1853409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        /* Check ASID, virtual page number & size */
185455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        if (unlikely((tlb->G == 1 || tlb->ASID == ASID) && VPN == tag)) {
1855409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            /* TLB match */
1856409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            env->CP0_Index = i;
1857409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            break;
1858409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        }
1859409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1860409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (i == env->tlb->nb_tlb) {
186155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        /* No match.  Discard any shadow entries, if any of them match. */
186255ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        int index = ((env->CP0_EntryHi>>5)&0x1ff00) | ASID;
186355ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman        index |= (env->CP0_EntryHi>>13)&0x20000;
1864409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->CP0_Index |= 0x80000000;
1865409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1866409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1867409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1868758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnervoid r4k_helper_tlbr(CPUMIPSState *env)
1869409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1870409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    r4k_tlb_t *tlb;
1871409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint8_t ASID;
1872409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1873409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    ASID = env->CP0_EntryHi & 0xFF;
187455ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    tlb = &env->tlb->mmu.r4k.tlb[env->CP0_Index % env->tlb->nb_tlb];
1875409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1876409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* If this will change the current ASID, flush qemu's TLB.  */
1877409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (ASID != tlb->ASID)
1878409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        cpu_mips_tlb_flush (env, 1);
1879409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
188055ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    /*flush all the tlb cache */
188155ff318b4e5382074e2049c996cb6df1041aff1bChris Dearman    cpu_mips_tlb_flush (env, 1);
1882409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1883409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_EntryHi = tlb->VPN | tlb->ASID;
1884409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_PageMask = tlb->PageMask;
1885409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) |
1886409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                        (tlb->C0 << 3) | (tlb->PFN[0] >> 6);
1887409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) |
1888409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                        (tlb->C1 << 3) | (tlb->PFN[1] >> 6);
1889409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1890409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1891758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnervoid helper_tlbwi(CPUMIPSState *env)
1892409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1893758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turner    env->tlb->helper_tlbwi(env);
1894409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1895409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1896758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnervoid helper_tlbwr(CPUMIPSState *env)
1897409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1898758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turner    env->tlb->helper_tlbwr(env);
1899409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1900409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1901758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnervoid helper_tlbp(CPUMIPSState *env)
1902409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1903758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turner    env->tlb->helper_tlbp(env);
1904409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1905409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1906758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turnervoid helper_tlbr(CPUMIPSState *env)
1907409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1908758fa08712c9b1075c49adf86fd0a24c8fdb30ecDavid 'Digit' Turner    env->tlb->helper_tlbr(env);
1909409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1910409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1911409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* Specials */
19126480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnertarget_ulong helper_di(CPUMIPSState *env)
1913409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1914409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong t0 = env->CP0_Status;
1915409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1916409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Status = t0 & ~(1 << CP0St_IE);
1917409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    cpu_mips_update_irq(env);
1918409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1919409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return t0;
1920409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1921409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
19226480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnertarget_ulong helper_ei(CPUMIPSState *env)
1923409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1924409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong t0 = env->CP0_Status;
1925409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1926409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_Status = t0 | (1 << CP0St_IE);
1927409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    cpu_mips_update_irq(env);
1928409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1929409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return t0;
1930409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1931409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
19326480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnerstatic void debug_pre_eret(CPUMIPSState *env)
1933409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1934409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
1935409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        qemu_log("ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
1936409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                env->active_tc.PC, env->CP0_EPC);
1937409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (env->CP0_Status & (1 << CP0St_ERL))
1938409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            qemu_log(" ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
1939409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (env->hflags & MIPS_HFLAG_DM)
1940409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
1941409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        qemu_log("\n");
1942409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1943409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1944409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
19456480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnerstatic void debug_post_eret(CPUMIPSState *env)
1946409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1947409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
1948409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        qemu_log("  =>  PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
1949409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                env->active_tc.PC, env->CP0_EPC);
1950409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (env->CP0_Status & (1 << CP0St_ERL))
1951409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            qemu_log(" ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
1952409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (env->hflags & MIPS_HFLAG_DM)
1953409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
1954409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        switch (env->hflags & MIPS_HFLAG_KSU) {
1955409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        case MIPS_HFLAG_UM: qemu_log(", UM\n"); break;
1956409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        case MIPS_HFLAG_SM: qemu_log(", SM\n"); break;
1957409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        case MIPS_HFLAG_KM: qemu_log("\n"); break;
1958409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        default: cpu_abort(env, "Invalid MMU mode!\n"); break;
1959409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        }
1960409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1961409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1962409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
19636480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnervoid helper_eret (CPUMIPSState *env)
1964409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
19656480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner    debug_pre_eret(env);
1966409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (env->CP0_Status & (1 << CP0St_ERL)) {
1967409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->active_tc.PC = env->CP0_ErrorEPC;
1968409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->CP0_Status &= ~(1 << CP0St_ERL);
1969409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    } else {
1970409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->active_tc.PC = env->CP0_EPC;
1971409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->CP0_Status &= ~(1 << CP0St_EXL);
1972409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
1973409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    compute_hflags(env);
19746480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner    debug_post_eret(env);
1975409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->lladdr = 1;
1976409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1977409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
19786480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turnervoid helper_deret (CPUMIPSState *env)
1979409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
19806480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner    debug_pre_eret(env);
1981409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->active_tc.PC = env->CP0_DEPC;
1982409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->hflags &= MIPS_HFLAG_DM;
1983409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    compute_hflags(env);
19846480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner    debug_post_eret(env);
1985409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->lladdr = 1;
1986409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1987409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif /* !CONFIG_USER_ONLY */
1988409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1989d5b76c63cc364a51cfd4ba45e2449c907a0a2e97David 'Digit' Turnertarget_ulong helper_rdhwr_cpunum(CPUMIPSState *env)
1990409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
1991409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if ((env->hflags & MIPS_HFLAG_CP0) ||
1992409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        (env->CP0_HWREna & (1 << 0)))
1993409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return env->CP0_EBase & 0x3ff;
1994409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
19956480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_RI);
1996409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
1997409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return 0;
1998409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
1999409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2000d5b76c63cc364a51cfd4ba45e2449c907a0a2e97David 'Digit' Turnertarget_ulong helper_rdhwr_synci_step(CPUMIPSState *env)
2001409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2002409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if ((env->hflags & MIPS_HFLAG_CP0) ||
2003409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        (env->CP0_HWREna & (1 << 1)))
2004409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return env->SYNCI_Step;
2005409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
20066480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_RI);
2007409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2008409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return 0;
2009409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2010409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2011d5b76c63cc364a51cfd4ba45e2449c907a0a2e97David 'Digit' Turnertarget_ulong helper_rdhwr_cc(CPUMIPSState *env)
2012409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2013409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if ((env->hflags & MIPS_HFLAG_CP0) ||
2014409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        (env->CP0_HWREna & (1 << 2)))
2015409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return env->CP0_Count;
2016409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
20176480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_RI);
2018409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2019409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return 0;
2020409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2021409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2022d5b76c63cc364a51cfd4ba45e2449c907a0a2e97David 'Digit' Turnertarget_ulong helper_rdhwr_ccres(CPUMIPSState *env)
2023409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2024409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if ((env->hflags & MIPS_HFLAG_CP0) ||
2025409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        (env->CP0_HWREna & (1 << 3)))
2026409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return env->CCRes;
2027409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
20286480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_RI);
2029409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2030409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return 0;
2031409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2032409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2033d5b76c63cc364a51cfd4ba45e2449c907a0a2e97David 'Digit' Turnervoid helper_pmon(CPUMIPSState *env, int function)
2034409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2035409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    function /= 2;
2036409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    switch (function) {
2037409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 2: /* TODO: char inbyte(int waitflag); */
2038409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (env->active_tc.gpr[4] == 0)
2039409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            env->active_tc.gpr[2] = -1;
2040409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        /* Fall through */
2041409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 11: /* TODO: char inbyte (void); */
2042409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->active_tc.gpr[2] = -1;
2043409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2044409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 3:
2045409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 12:
2046409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        printf("%c", (char)(env->active_tc.gpr[4] & 0xFF));
2047409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2048409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 17:
2049409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2050409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 158:
2051409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        {
2052409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            unsigned char *fmt = (void *)(unsigned long)env->active_tc.gpr[4];
2053409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            printf("%s", fmt);
2054409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        }
2055409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2056409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
2057409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2058409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2059d5b76c63cc364a51cfd4ba45e2449c907a0a2e97David 'Digit' Turnervoid helper_wait(CPUMIPSState *env)
2060409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
20616657678c3d86395084f6a699e73614195f06c445David 'Digit' Turner    ENV_GET_CPU(env)->halted = 1;
20626480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner    helper_raise_exception(env, EXCP_HLT);
2063409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2064409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2065409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#if !defined(CONFIG_USER_ONLY)
2066409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
20676cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turnerstatic void do_unaligned_access (CPUMIPSState *env,
2068589fe9bc37aebf62e6d80c371d47a19e52a5f58aDavid 'Digit' Turner                                 target_ulong addr, int is_write,
2069eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner                                 int is_user, uintptr_t retaddr);
2070409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2071409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define MMUSUFFIX _mmu
2072409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define ALIGNED_ONLY
2073409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2074409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define SHIFT 0
2075852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_template.h"
2076409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2077409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define SHIFT 1
2078852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_template.h"
2079409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2080409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define SHIFT 2
2081852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_template.h"
2082409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2083409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define SHIFT 3
2084852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_template.h"
2085409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
20866cca40ecfdecbf496d5f07681e4b619f48db2f4dDavid 'Digit' Turnerstatic void do_unaligned_access(CPUMIPSState *env, target_ulong addr,
208765b44d50a84dd1272547c001ea5ecca62879e9aaDavid 'Digit' Turner                                int is_write, int is_user, uintptr_t retaddr)
2088409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2089409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    env->CP0_BadVAddr = addr;
20906480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner    do_restore_state (env, retaddr);
20916480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner    helper_raise_exception(env, (is_write == 1) ? EXCP_AdES : EXCP_AdEL);
2092409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2093409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
209465b44d50a84dd1272547c001ea5ecca62879e9aaDavid 'Digit' Turnervoid tlb_fill (CPUMIPSState* env, target_ulong addr, int is_write, int mmu_idx,
2095eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner               uintptr_t retaddr)
2096409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2097409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    TranslationBlock *tb;
2098409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int ret;
2099409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
21000d8b235c0c6c02de86a4e7415d574175b4518ff0David 'Digit' Turner    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx);
2101409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (ret) {
2102409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (retaddr) {
2103409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            /* now we have a real cpu fault */
2104eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner            tb = tb_find_pc(retaddr);
2105409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            if (tb) {
2106409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                /* the PC is inside the translated code. It means that we have
2107409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                   a virtual CPU fault */
2108eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner                cpu_restore_state(env, retaddr);
2109409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            }
2110409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        }
21116480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception_err(env, env->exception_index, env->error_code);
2112409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
2113409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2114409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
211565b44d50a84dd1272547c001ea5ecca62879e9aaDavid 'Digit' Turnervoid cpu_unassigned_access(CPUMIPSState* env, hwaddr addr,
21166cf763a179bb432ef845025bb3639fcaf1251bd0David 'Digit' Turner                           int is_write, int is_exec, int unused, int size)
2117409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2118409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (is_exec)
21196480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_IBE);
2120409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
21216480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_DBE);
2122409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2123325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli/*
2124c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner * The following functions are address translation helper functions
2125c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner * for fast memory access in QEMU.
2126325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli */
212765b44d50a84dd1272547c001ea5ecca62879e9aaDavid 'Digit' Turnerstatic unsigned long v2p_mmu(CPUMIPSState *env, target_ulong addr, int is_user)
2128325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli{
2129325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    int index;
2130325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    target_ulong tlb_addr;
2131eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner    hwaddr physaddr;
2132eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner    uintptr_t retaddr;
2133325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli
2134325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
2135325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalliredo:
2136325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    tlb_addr = env->tlb_table[is_user][index].addr_read;
2137325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
2138325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        physaddr = addr + env->tlb_table[is_user][index].addend;
2139325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    } else {
2140325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        /* the page is not in the TLB : fill it */
2141325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        retaddr = GETPC();
21426d1afd3bf737fe15c9ba2a23c2f957ae8ff2e663David 'Digit' Turner        tlb_fill(env, addr, 0, is_user, retaddr);
2143325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        goto redo;
2144325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    }
2145325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    return physaddr;
2146325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli}
2147325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli
2148c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner/*
2149c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner * translation from virtual address of simulated OS
2150c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner * to the address of simulation host (not the physical
2151325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli * address of simulated OS.
2152325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli */
2153342a01fc826881e6b12b7673c7d2c280295f4d9eDuane Sandunsigned long v2p(target_ulong ptr, int is_user)
2154325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli{
215565b44d50a84dd1272547c001ea5ecca62879e9aaDavid 'Digit' Turner    CPUMIPSState *env;
2156325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    int index;
2157325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    target_ulong addr;
2158eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner    hwaddr physaddr;
2159325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli
2160325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    env = cpu_single_env;
2161325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    addr = ptr;
2162325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
2163c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner    if (__builtin_expect(env->tlb_table[is_user][index].addr_read !=
2164325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli                (addr & TARGET_PAGE_MASK), 0)) {
216565b44d50a84dd1272547c001ea5ecca62879e9aaDavid 'Digit' Turner        physaddr = v2p_mmu(env, addr, is_user);
2166325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    } else {
2167342a01fc826881e6b12b7673c7d2c280295f4d9eDuane Sand        physaddr = addr + env->tlb_table[is_user][index].addend;
2168325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    }
2169325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    return physaddr;
2170325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli}
2171325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli
2172325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli/* copy a string from the simulated virtual space to a buffer in QEMU */
2173325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapallivoid vstrcpy(target_ulong ptr, char *buf, int max)
2174325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli{
2175325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    char *phys = 0;
2176eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner    target_ulong page = 0;
2177325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli
2178325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    if (buf == NULL) return;
2179325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli
2180325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    while (max) {
2181325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        if ((ptr & TARGET_PAGE_MASK) != page) {
2182325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli            phys = (char *)v2p(ptr, 0);
2183325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli            page = ptr & TARGET_PAGE_MASK;
2184325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        }
2185325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        *buf = *phys;
2186325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        if (*phys == '\0')
2187325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli            return;
2188325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        ptr ++;
2189325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        buf ++;
2190325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        phys ++;
2191325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        max --;
2192325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    }
2193325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli}
2194325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli
2195409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif /* !CONFIG_USER_ONLY */
2196409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2197409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* Complex FPU operations which may need stack space. */
2198409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2199409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_ONE32 make_float32(0x3f8 << 20)
2200409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_ONE64 make_float64(0x3ffULL << 52)
2201409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_TWO32 make_float32(1 << 30)
2202409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_TWO64 make_float64(1ULL << 62)
2203409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_QNAN32 0x7fbfffff
2204409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_QNAN64 0x7ff7ffffffffffffULL
2205409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_SNAN32 0x7fffffff
2206409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_SNAN64 0x7fffffffffffffffULL
2207409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2208409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* convert MIPS rounding mode in FCR31 to IEEE library */
2209409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic unsigned int ieee_rm[] = {
2210409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    float_round_nearest_even,
2211409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    float_round_to_zero,
2212409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    float_round_up,
2213409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    float_round_down
2214409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli};
2215409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2216409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define RESTORE_ROUNDING_MODE \
2217409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status)
2218409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2219409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define RESTORE_FLUSH_MODE \
2220409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_flush_to_zero((env->active_fpu.fcr31 & (1 << 24)) != 0, &env->active_fpu.fp_status);
2221409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
222287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turnertarget_ulong helper_cfc1 (CPUMIPSState *env, uint32_t reg)
2223409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2224409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    target_ulong arg1;
2225409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2226409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    switch (reg) {
2227409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 0:
2228409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (int32_t)env->active_fpu.fcr0;
2229409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2230409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 25:
2231409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | ((env->active_fpu.fcr31 >> 23) & 0x1);
2232409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2233409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 26:
2234409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = env->active_fpu.fcr31 & 0x0003f07c;
2235409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2236409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 28:
2237409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (env->active_fpu.fcr31 & 0x00000f83) | ((env->active_fpu.fcr31 >> 22) & 0x4);
2238409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2239409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    default:
2240409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        arg1 = (int32_t)env->active_fpu.fcr31;
2241409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2242409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
2243409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2244409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return arg1;
2245409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2246409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
224787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turnervoid helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t reg)
2248409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2249409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    switch(reg) {
2250409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 25:
2251409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (arg1 & 0xffffff00)
2252409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            return;
2253409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) | ((arg1 & 0xfe) << 24) |
2254409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                     ((arg1 & 0x1) << 23);
2255409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2256409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 26:
2257409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (arg1 & 0x007c0000)
2258409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            return;
2259409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) | (arg1 & 0x0003f07c);
2260409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2261409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 28:
2262409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (arg1 & 0x007c0000)
2263409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            return;
2264409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) | (arg1 & 0x00000f83) |
2265409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                     ((arg1 & 0x4) << 22);
2266409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2267409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    case 31:
2268409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        if (arg1 & 0x007c0000)
2269409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli            return;
2270409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        env->active_fpu.fcr31 = arg1;
2271409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        break;
2272409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    default:
2273409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return;
2274409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
2275409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* set rounding mode */
2276409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
2277409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    /* set flush-to-zero mode */
2278409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_FLUSH_MODE;
2279409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2280409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) & GET_FP_CAUSE(env->active_fpu.fcr31))
22816480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_FPE);
2282409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2283409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2284409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic inline char ieee_ex_to_mips(char xcpt)
2285409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2286409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return (xcpt & float_flag_inexact) >> 5 |
2287409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli           (xcpt & float_flag_underflow) >> 3 |
2288409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli           (xcpt & float_flag_overflow) >> 1 |
2289409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli           (xcpt & float_flag_divbyzero) << 1 |
2290409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli           (xcpt & float_flag_invalid) << 4;
2291409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2292409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2293409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic inline char mips_ex_to_ieee(char xcpt)
2294409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2295409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return (xcpt & FP_INEXACT) << 5 |
2296409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli           (xcpt & FP_UNDERFLOW) << 3 |
2297409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli           (xcpt & FP_OVERFLOW) << 1 |
2298409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli           (xcpt & FP_DIV0) >> 1 |
2299409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli           (xcpt & FP_INVALID) >> 4;
2300409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2301409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
230287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turnerstatic inline void update_fcr31(CPUMIPSState *env)
2303409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2304409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->active_fpu.fp_status));
2305409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2306409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    SET_FP_CAUSE(env->active_fpu.fcr31, tmp);
2307409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_ENABLE(env->active_fpu.fcr31) & tmp)
23086480c96e71da41f7600478bc0d809f737090b35fDavid 'Digit' Turner        helper_raise_exception(env, EXCP_FPE);
2309409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else
2310409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        UPDATE_FP_FLAGS(env->active_fpu.fcr31, tmp);
2311409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2312409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2313409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* Float support.
2314409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli   Single precition routines have a "s" suffix, double precision a
2315409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli   "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
2316409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli   paired single lower "pl", paired single upper "pu".  */
2317409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2318409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* unary operations, modifying fp status  */
231987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
2320409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2321409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return float64_sqrt(fdt0, &env->active_fpu.fp_status);
2322409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2323409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
232487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
2325409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2326409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return float32_sqrt(fst0, &env->active_fpu.fp_status);
2327409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2328409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
232987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
2330409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2331409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t fdt2;
2332409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2333409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2334409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
233587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2336409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fdt2;
2337409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2338409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
233987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
2340409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2341409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t fdt2;
2342409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2343409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2344409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
234587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2346409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fdt2;
2347409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2348409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
234987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
2350409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2351409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t fdt2;
2352409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2353409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2354409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
235587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2356409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fdt2;
2357409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2358409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
235987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_cvtl_d(CPUMIPSState *env, uint64_t fdt0)
2360409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2361409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2362409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2363409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2364409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
236587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2366409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2367409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2368409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2369409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2370409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
237187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_cvtl_s(CPUMIPSState *env, uint32_t fst0)
2372409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2373409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2374409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2375409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2376409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
237787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2378409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2379409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2380409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2381409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2382409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
238387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
2384409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2385409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2386409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth2;
2387409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2388409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2389409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
2390409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
239187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2392409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)fsth2 << 32) | fst2;
2393409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2394409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
239587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
2396409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2397409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2398409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wth2;
2399409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2400409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2401409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
2402409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
240387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2404409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID)) {
2405409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2406409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wth2 = FLOAT_SNAN32;
2407409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
2408409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)wth2 << 32) | wt2;
2409409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2410409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
241187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
2412409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2413409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2414409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2415409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2416409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
241787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2418409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fst2;
2419409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2420409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
242187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
2422409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2423409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2424409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2425409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2426409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
242787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2428409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fst2;
2429409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2430409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
243187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
2432409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2433409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2434409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2435409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2436409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
243787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2438409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fst2;
2439409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2440409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
244187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
2442409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2443409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2444409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2445409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2446409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = wt0;
244787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2448409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2449409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2450409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
245187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
2452409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2453409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2454409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2455409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2456409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = wth0;
245787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2458409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2459409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2460409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
246187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_cvtw_s(CPUMIPSState *env, uint32_t fst0)
2462409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2463409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2464409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2465409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2466409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
246787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2468409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2469409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2470409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2471409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2472409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
247387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_cvtw_d(CPUMIPSState *env, uint64_t fdt0)
2474409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2475409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2476409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2477409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2478409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
247987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2480409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2481409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2482409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2483409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2484409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
248587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_roundl_d(CPUMIPSState *env, uint64_t fdt0)
2486409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2487409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2488409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
24895b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2490409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
2491409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
2492409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
249387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2494409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2495409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2496409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2497409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2498409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
249987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_roundl_s(CPUMIPSState *env, uint32_t fst0)
2500409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2501409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2502409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
25035b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2504409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
2505409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
2506409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
250787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2508409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2509409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2510409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2511409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2512409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
251387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_roundw_d(CPUMIPSState *env, uint64_t fdt0)
2514409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2515409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2516409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
25175b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2518409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
2519409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
2520409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
252187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2522409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2523409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2524409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2525409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2526409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
252787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_roundw_s(CPUMIPSState *env, uint32_t fst0)
2528409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2529409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2530409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
25315b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2532409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
2533409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
2534409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
253587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2536409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2537409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2538409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2539409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2540409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
254187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_truncl_d(CPUMIPSState *env, uint64_t fdt0)
2542409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2543409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2544409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
25455b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2546409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
254787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2548409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2549409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2550409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2551409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2552409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
255387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_truncl_s(CPUMIPSState *env, uint32_t fst0)
2554409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2555409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2556409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
25575b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2558409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
255987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2560409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2561409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2562409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2563409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2564409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
256587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_truncw_d(CPUMIPSState *env, uint64_t fdt0)
2566409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2567409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2568409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
25695b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2570409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
257187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2572409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2573409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2574409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2575409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2576409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
257787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_truncw_s(CPUMIPSState *env, uint32_t fst0)
2578409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2579409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2580409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
25815b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2582409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
258387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2584409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2585409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2586409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2587409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2588409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
258987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_ceill_d(CPUMIPSState *env, uint64_t fdt0)
2590409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2591409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2592409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
25935b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2594409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
2595409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
2596409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
259787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2598409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2599409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2600409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2601409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2602409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
260387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_ceill_s(CPUMIPSState *env, uint32_t fst0)
2604409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2605409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2606409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
26075b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2608409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
2609409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
2610409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
261187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2612409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2613409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2614409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2615409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2616409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
261787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_ceilw_d(CPUMIPSState *env, uint64_t fdt0)
2618409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2619409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2620409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
26215b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2622409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
2623409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
2624409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
262587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2626409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2627409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2628409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2629409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2630409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
263187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_ceilw_s(CPUMIPSState *env, uint32_t fst0)
2632409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2633409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2634409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
26355b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2636409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
2637409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
2638409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
263987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2640409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2641409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2642409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2643409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2644409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
264587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_floorl_d(CPUMIPSState *env, uint64_t fdt0)
2646409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2647409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2648409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
26495b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2650409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
2651409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
2652409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
265387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2654409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2655409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2656409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2657409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2658409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
265987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_floorl_s(CPUMIPSState *env, uint32_t fst0)
2660409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2661409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;
2662409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
26635b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2664409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
2665409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
2666409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
266787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2668409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2669409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_SNAN64;
2670409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;
2671409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2672409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
267387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_floorw_d(CPUMIPSState *env, uint64_t fdt0)
2674409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2675409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2676409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
26775b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2678409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
2679409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
2680409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
268187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2682409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2683409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2684409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2685409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2686409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
268787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_floorw_s(CPUMIPSState *env, uint32_t fst0)
2688409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2689409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;
2690409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
26915b954e623db71d3df2d9af1825ec3815137a06a7Bhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2692409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
2693409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
2694409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    RESTORE_ROUNDING_MODE;
269587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2696409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
2697409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_SNAN32;
2698409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;
2699409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2700409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2701409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* unary operations, not modifying fp status  */
2702409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_UNOP(name)                                       \
2703409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalliuint64_t helper_float_ ## name ## _d(uint64_t fdt0)                \
2704409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                              \
2705409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return float64_ ## name(fdt0);                             \
2706409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                              \
2707409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalliuint32_t helper_float_ ## name ## _s(uint32_t fst0)                \
2708409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                              \
2709409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return float32_ ## name(fst0);                             \
2710409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                              \
2711409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalliuint64_t helper_float_ ## name ## _ps(uint64_t fdt0)               \
2712409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                              \
2713409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt0;                                              \
2714409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wth0;                                             \
2715409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                               \
2716409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt0 = float32_ ## name(fdt0 & 0XFFFFFFFF);                 \
2717409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wth0 = float32_ ## name(fdt0 >> 32);                       \
2718409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)wth0 << 32) | wt0;                       \
2719409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2720409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_UNOP(abs)
2721409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_UNOP(chs)
2722409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#undef FLOAT_UNOP
2723409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2724409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* MIPS specific unary operations */
272587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
2726409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2727409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t fdt2;
2728409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2729409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2730409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->active_fpu.fp_status);
273187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2732409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fdt2;
2733409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2734409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
273587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
2736409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2737409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2738409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2739409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2740409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_div(FLOAT_ONE32, fst0, &env->active_fpu.fp_status);
274187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2742409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fst2;
2743409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2744409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
274587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
2746409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2747409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t fdt2;
2748409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2749409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2750409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
2751409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->active_fpu.fp_status);
275287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2753409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fdt2;
2754409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2755409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
275687350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
2757409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2758409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2759409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2760409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2761409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
2762409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_div(FLOAT_ONE32, fst2, &env->active_fpu.fp_status);
276387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2764409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fst2;
2765409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2766409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
276787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
2768409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2769409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t fdt2;
2770409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2771409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2772409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->active_fpu.fp_status);
277387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2774409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fdt2;
2775409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2776409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
277787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
2778409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2779409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2780409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2781409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2782409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_div(FLOAT_ONE32, fst0, &env->active_fpu.fp_status);
278387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2784409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fst2;
2785409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2786409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
278787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
2788409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2789409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2790409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth2;
2791409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2792409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2793409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_div(FLOAT_ONE32, fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
2794409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_div(FLOAT_ONE32, fdt0 >> 32, &env->active_fpu.fp_status);
279587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2796409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)fsth2 << 32) | fst2;
2797409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2798409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
279987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
2800409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2801409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t fdt2;
2802409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2803409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2804409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
2805409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->active_fpu.fp_status);
280687350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2807409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fdt2;
2808409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2809409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
281087350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
2811409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2812409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2813409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2814409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2815409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
2816409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_div(FLOAT_ONE32, fst2, &env->active_fpu.fp_status);
281787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2818409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fst2;
2819409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2820409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
282187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
2822409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2823409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
2824409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth2;
2825409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2826409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2827409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
2828409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
2829409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_div(FLOAT_ONE32, fst2, &env->active_fpu.fp_status);
2830409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_div(FLOAT_ONE32, fsth2, &env->active_fpu.fp_status);
283187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2832409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)fsth2 << 32) | fst2;
2833409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2834409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
283587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner#define FLOAT_OP(name, p) void helper_float_##name##_##p(CPUMIPSState *env)
2836409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2837409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* binary operations */
2838409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_BINOP(name)                                          \
283987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_ ## name ## _d(CPUMIPSState *env,            \
284087350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                     uint64_t fdt0, uint64_t fdt1) \
2841409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                  \
2842409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint64_t dt2;                                                  \
2843409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                   \
2844409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);            \
2845409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    dt2 = float64_ ## name (fdt0, fdt1, &env->active_fpu.fp_status);     \
284687350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);                                                \
2847409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID)                \
2848409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        dt2 = FLOAT_QNAN64;                                        \
2849409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return dt2;                                                    \
2850409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                                  \
2851409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                   \
285287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_ ## name ## _s(CPUMIPSState *env,            \
285387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                     uint32_t fst0, uint32_t fst1) \
2854409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                  \
2855409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;                                                  \
2856409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                   \
2857409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);            \
2858409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float32_ ## name (fst0, fst1, &env->active_fpu.fp_status);     \
285987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);                                                \
2860409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID)                \
2861409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_QNAN32;                                        \
2862409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return wt2;                                                    \
2863409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                                  \
2864409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                   \
286587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,           \
286687350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                      uint64_t fdt0,               \
286787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                      uint64_t fdt1)               \
2868409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                  \
2869409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst0 = fdt0 & 0XFFFFFFFF;                             \
2870409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth0 = fdt0 >> 32;                                   \
2871409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst1 = fdt1 & 0XFFFFFFFF;                             \
2872409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth1 = fdt1 >> 32;                                   \
2873409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wt2;                                                  \
2874409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t wth2;                                                 \
2875409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                   \
2876409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);            \
2877409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wt2 = float32_ ## name (fst0, fst1, &env->active_fpu.fp_status);     \
2878409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    wth2 = float32_ ## name (fsth0, fsth1, &env->active_fpu.fp_status);  \
287987350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);                                                \
2880409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID) {              \
2881409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wt2 = FLOAT_QNAN32;                                        \
2882409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        wth2 = FLOAT_QNAN32;                                       \
2883409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }                                                              \
2884409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)wth2 << 32) | wt2;                           \
2885409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2886409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2887409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_BINOP(add)
2888409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_BINOP(sub)
2889409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_BINOP(mul)
2890409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_BINOP(div)
2891409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#undef FLOAT_BINOP
2892409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2893409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* ternary operations */
2894409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_TERNOP(name1, name2)                                        \
289587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_ ## name1 ## name2 ## _d(CPUMIPSState *env,         \
289687350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                           uint64_t fdt0, uint64_t fdt1,  \
2897409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                           uint64_t fdt2)                 \
2898409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                         \
2899409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt0 = float64_ ## name1 (fdt0, fdt1, &env->active_fpu.fp_status);          \
2900409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return float64_ ## name2 (fdt0, fdt2, &env->active_fpu.fp_status);          \
2901409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                                         \
2902409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                          \
290387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_ ## name1 ## name2 ## _s(CPUMIPSState *env,         \
290487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                           uint32_t fst0, uint32_t fst1,  \
2905409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                           uint32_t fst2)                 \
2906409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                         \
2907409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
2908409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
2909409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                                         \
2910409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                          \
291187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_ ## name1 ## name2 ## _ps(CPUMIPSState *env,        \
291287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                            uint64_t fdt0, uint64_t fdt1, \
2913409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                            uint64_t fdt2)                \
2914409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                         \
2915409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst0 = fdt0 & 0XFFFFFFFF;                                    \
2916409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth0 = fdt0 >> 32;                                          \
2917409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst1 = fdt1 & 0XFFFFFFFF;                                    \
2918409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth1 = fdt1 >> 32;                                          \
2919409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2 = fdt2 & 0XFFFFFFFF;                                    \
2920409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth2 = fdt2 >> 32;                                          \
2921409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                          \
2922409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
2923409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth0 = float32_ ## name1 (fsth0, fsth1, &env->active_fpu.fp_status);       \
2924409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
2925409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_ ## name2 (fsth0, fsth2, &env->active_fpu.fp_status);       \
2926409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)fsth2 << 32) | fst2;                                \
2927409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2928409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2929409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_TERNOP(mul, add)
2930409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_TERNOP(mul, sub)
2931409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#undef FLOAT_TERNOP
2932409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2933409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* negated ternary operations */
2934409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FLOAT_NTERNOP(name1, name2)                                       \
293587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_n ## name1 ## name2 ## _d(CPUMIPSState *env,        \
293687350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                           uint64_t fdt0, uint64_t fdt1, \
2937409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                           uint64_t fdt2)                 \
2938409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                         \
2939409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt0 = float64_ ## name1 (fdt0, fdt1, &env->active_fpu.fp_status);          \
2940409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_ ## name2 (fdt0, fdt2, &env->active_fpu.fp_status);          \
2941409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return float64_chs(fdt2);                                             \
2942409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                                         \
2943409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                          \
294487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_n ## name1 ## name2 ## _s(CPUMIPSState *env,        \
294587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                           uint32_t fst0, uint32_t fst1, \
2946409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                           uint32_t fst2)                 \
2947409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                         \
2948409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
2949409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
2950409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return float32_chs(fst2);                                             \
2951409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                                         \
2952409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                          \
295387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_n ## name1 ## name2 ## _ps(CPUMIPSState *env,       \
295487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                                           uint64_t fdt0, uint64_t fdt1,\
2955409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                           uint64_t fdt2)                 \
2956409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                                         \
2957409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst0 = fdt0 & 0XFFFFFFFF;                                    \
2958409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth0 = fdt0 >> 32;                                          \
2959409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst1 = fdt1 & 0XFFFFFFFF;                                    \
2960409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth1 = fdt1 >> 32;                                          \
2961409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2 = fdt2 & 0XFFFFFFFF;                                    \
2962409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth2 = fdt2 >> 32;                                          \
2963409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                          \
2964409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
2965409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth0 = float32_ ## name1 (fsth0, fsth1, &env->active_fpu.fp_status);       \
2966409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
2967409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_ ## name2 (fsth0, fsth2, &env->active_fpu.fp_status);       \
2968409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_chs(fst2);                                             \
2969409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_chs(fsth2);                                           \
2970409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)fsth2 << 32) | fst2;                                \
2971409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2972409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2973409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_NTERNOP(mul, add)
2974409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFLOAT_NTERNOP(mul, sub)
2975409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#undef FLOAT_NTERNOP
2976409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
2977409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* MIPS specific binary operations */
297887350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
2979409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2980409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2981409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
2982409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_chs(float64_sub(fdt2, FLOAT_ONE64, &env->active_fpu.fp_status));
298387350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2984409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fdt2;
2985409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2986409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
298787350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
2988409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2989409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
2990409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
2991409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status));
299287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
2993409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fst2;
2994409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
2995409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
299687350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
2997409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
2998409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst0 = fdt0 & 0XFFFFFFFF;
2999409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth0 = fdt0 >> 32;
3000409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2 = fdt2 & 0XFFFFFFFF;
3001409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth2 = fdt2 >> 32;
3002409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3003409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
3004409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
3005409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
3006409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status));
3007409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_chs(float32_sub(fsth2, FLOAT_ONE32, &env->active_fpu.fp_status));
300887350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
3009409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)fsth2 << 32) | fst2;
3010409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3011409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
301287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
3013409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3014409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
3015409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
3016409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_sub(fdt2, FLOAT_ONE64, &env->active_fpu.fp_status);
3017409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64, &env->active_fpu.fp_status));
301887350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
3019409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fdt2;
3020409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3021409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
302287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
3023409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3024409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
3025409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
3026409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status);
3027409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->active_fpu.fp_status));
302887350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
3029409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return fst2;
3030409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3031409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
303287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
3033409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3034409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst0 = fdt0 & 0XFFFFFFFF;
3035409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth0 = fdt0 >> 32;
3036409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2 = fdt2 & 0XFFFFFFFF;
3037409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth2 = fdt2 >> 32;
3038409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3039409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
3040409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
3041409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
3042409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status);
3043409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_sub(fsth2, FLOAT_ONE32, &env->active_fpu.fp_status);
3044409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->active_fpu.fp_status));
3045409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32, &env->active_fpu.fp_status));
304687350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
3047409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)fsth2 << 32) | fst2;
3048409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3049409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
305087350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
3051409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3052409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst0 = fdt0 & 0XFFFFFFFF;
3053409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth0 = fdt0 >> 32;
3054409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst1 = fdt1 & 0XFFFFFFFF;
3055409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth1 = fdt1 >> 32;
3056409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
3057409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth2;
3058409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3059409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
3060409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_add (fst0, fsth0, &env->active_fpu.fp_status);
3061409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_add (fst1, fsth1, &env->active_fpu.fp_status);
306287350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
3063409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)fsth2 << 32) | fst2;
3064409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3065409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
306687350d189097667bf170a57ee54347498511dfb6David 'Digit' Turneruint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
3067409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3068409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst0 = fdt0 & 0XFFFFFFFF;
3069409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth0 = fdt0 >> 32;
3070409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst1 = fdt1 & 0XFFFFFFFF;
3071409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth1 = fdt1 >> 32;
3072409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst2;
3073409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth2;
3074409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3075409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    set_float_exception_flags(0, &env->active_fpu.fp_status);
3076409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst2 = float32_mul (fst0, fsth0, &env->active_fpu.fp_status);
3077409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fsth2 = float32_mul (fst1, fsth1, &env->active_fpu.fp_status);
307887350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);
3079409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    return ((uint64_t)fsth2 << 32) | fst2;
3080409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3081409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3082409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* compare operations */
3083409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FOP_COND_D(op, cond)                                   \
308487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turnervoid helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
308587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                         uint64_t fdt1, int cc)                \
3086409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                              \
3087409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int c = cond;                                              \
308887350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);                                            \
3089409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (c)                                                     \
3090409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        SET_FP_COND(cc, env->active_fpu);                      \
3091409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else                                                       \
3092409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        CLEAR_FP_COND(cc, env->active_fpu);                    \
3093409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                              \
309487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turnervoid helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
309587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                            uint64_t fdt1, int cc)             \
3096409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                              \
3097409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int c;                                                     \
3098409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt0 = float64_abs(fdt0);                                  \
3099409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fdt1 = float64_abs(fdt1);                                  \
3100409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    c = cond;                                                  \
310187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);                                            \
3102409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (c)                                                     \
3103409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        SET_FP_COND(cc, env->active_fpu);                      \
3104409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else                                                       \
3105409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        CLEAR_FP_COND(cc, env->active_fpu);                    \
3106409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3107409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3108409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic int float64_is_unordered(int sig, float64 a, float64 b STATUS_PARAM)
3109409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3110409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (float64_is_signaling_nan(a) ||
3111409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        float64_is_signaling_nan(b) ||
3112325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        (sig && (float64_is_any_nan(a) || float64_is_any_nan(b)))) {
3113409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        float_raise(float_flag_invalid, status);
3114409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return 1;
3115325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    } else if (float64_is_any_nan(a) || float64_is_any_nan(b)) {
3116409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return 1;
3117409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    } else {
3118409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return 0;
3119409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
3120409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3121409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3122409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* NOTE: the comma operator will make "cond" to eval to false,
3123409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * but float*_is_unordered() is still called. */
3124409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(f,   (float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status), 0))
3125409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(un,  float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status))
3126409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(eq,  !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
3127409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(ueq, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
3128409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(olt, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
3129409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(ult, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
3130409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(ole, !float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
3131409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(ule, float64_is_unordered(0, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
3132409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* NOTE: the comma operator will make "cond" to eval to false,
3133409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * but float*_is_unordered() is still called. */
3134409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(sf,  (float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status), 0))
3135409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(ngle,float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status))
3136409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(seq, !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
3137409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(ngl, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_eq(fdt0, fdt1, &env->active_fpu.fp_status))
3138409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(lt,  !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
3139409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(nge, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_lt(fdt0, fdt1, &env->active_fpu.fp_status))
3140409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(le,  !float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status) && float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
3141409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_D(ngt, float64_is_unordered(1, fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
3142409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3143409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FOP_COND_S(op, cond)                                   \
314487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turnervoid helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,     \
314587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                         uint32_t fst1, int cc)                \
3146409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                              \
3147409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int c = cond;                                              \
314887350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);                                            \
3149409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (c)                                                     \
3150409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        SET_FP_COND(cc, env->active_fpu);                      \
3151409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else                                                       \
3152409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        CLEAR_FP_COND(cc, env->active_fpu);                    \
3153409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                              \
315487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turnervoid helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0,  \
315587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                            uint32_t fst1, int cc)             \
3156409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                              \
3157409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int c;                                                     \
3158409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst0 = float32_abs(fst0);                                  \
3159409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    fst1 = float32_abs(fst1);                                  \
3160409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    c = cond;                                                  \
316187350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);                                            \
3162409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (c)                                                     \
3163409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        SET_FP_COND(cc, env->active_fpu);                      \
3164409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else                                                       \
3165409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        CLEAR_FP_COND(cc, env->active_fpu);                    \
3166409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3167409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3168409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic flag float32_is_unordered(int sig, float32 a, float32 b STATUS_PARAM)
3169409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{
3170409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (float32_is_signaling_nan(a) ||
3171409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        float32_is_signaling_nan(b) ||
3172325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli        (sig && (float32_is_any_nan(a) || float32_is_any_nan(b)))) {
3173409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        float_raise(float_flag_invalid, status);
3174409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return 1;
3175325e19d19ff9e1fc9c6acb12eeb754563fc2e251Bhanu Chetlapalli    } else if (float32_is_any_nan(a) || float32_is_any_nan(b)) {
3176409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return 1;
3177409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    } else {
3178409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        return 0;
3179409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    }
3180409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3181409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3182409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* NOTE: the comma operator will make "cond" to eval to false,
3183409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * but float*_is_unordered() is still called. */
3184409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(f,   (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0))
3185409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(un,  float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status))
3186409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(eq,  !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
3187409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
3188409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
3189409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
3190409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
3191409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
3192409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* NOTE: the comma operator will make "cond" to eval to false,
3193409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * but float*_is_unordered() is still called. */
3194409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(sf,  (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0))
3195409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status))
3196409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_eq(fst0, fst1, &env->active_fpu.fp_status))
3197409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_eq(fst0, fst1, &env->active_fpu.fp_status))
3198409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(lt,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_lt(fst0, fst1, &env->active_fpu.fp_status))
3199409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_lt(fst0, fst1, &env->active_fpu.fp_status))
3200409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(le,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status) && float32_le(fst0, fst1, &env->active_fpu.fp_status))
3201409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_S(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
3202409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3203409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define FOP_COND_PS(op, condl, condh)                           \
320487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turnervoid helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
320587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                          uint64_t fdt1, int cc)                \
3206409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                               \
3207409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF);             \
3208409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth0 = float32_abs(fdt0 >> 32);                   \
3209409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF);             \
3210409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth1 = float32_abs(fdt1 >> 32);                   \
3211409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int cl = condl;                                             \
3212409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int ch = condh;                                             \
3213409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                \
321487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);                                             \
3215409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (cl)                                                     \
3216409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        SET_FP_COND(cc, env->active_fpu);                       \
3217409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else                                                        \
3218409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        CLEAR_FP_COND(cc, env->active_fpu);                     \
3219409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (ch)                                                     \
3220409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        SET_FP_COND(cc + 1, env->active_fpu);                   \
3221409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else                                                        \
3222409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
3223409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}                                                               \
322487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turnervoid helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
322587350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner                             uint64_t fdt1, int cc)             \
3226409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{                                                               \
3227409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst0 = float32_abs(fdt0 & 0XFFFFFFFF);             \
3228409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth0 = float32_abs(fdt0 >> 32);                   \
3229409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fst1 = float32_abs(fdt1 & 0XFFFFFFFF);             \
3230409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    uint32_t fsth1 = float32_abs(fdt1 >> 32);                   \
3231409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int cl = condl;                                             \
3232409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    int ch = condh;                                             \
3233409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                                                                \
323487350d189097667bf170a57ee54347498511dfb6David 'Digit' Turner    update_fcr31(env);                                             \
3235409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (cl)                                                     \
3236409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        SET_FP_COND(cc, env->active_fpu);                       \
3237409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else                                                        \
3238409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        CLEAR_FP_COND(cc, env->active_fpu);                     \
3239409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    if (ch)                                                     \
3240409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        SET_FP_COND(cc + 1, env->active_fpu);                   \
3241409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli    else                                                        \
3242409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli        CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
3243409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}
3244409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli
3245409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* NOTE: the comma operator will make "cond" to eval to false,
3246409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * but float*_is_unordered() is still called. */
3247409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(f,   (float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status), 0),
3248409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 (float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status), 0))
3249409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(un,  float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status),
3250409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status))
3251409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(eq,  !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
3252409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
3253409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(ueq, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
3254409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
3255409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(olt, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
3256409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
3257409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(ult, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
3258409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
3259409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(ole, !float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
3260409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 !float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
3261409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(ule, float32_is_unordered(0, fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
3262409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 float32_is_unordered(0, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
3263409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* NOTE: the comma operator will make "cond" to eval to false,
3264409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * but float*_is_unordered() is still called. */
3265409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(sf,  (float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status), 0),
3266409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 (float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status), 0))
3267409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(ngle,float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status),
3268409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status))
3269409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(seq, !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_eq(fst0, fst1, &env->active_fpu.fp_status),
3270409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
3271409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(ngl, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_eq(fst0, fst1, &env->active_fpu.fp_status),
3272409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_eq(fsth0, fsth1, &env->active_fpu.fp_status))
3273409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(lt,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_lt(fst0, fst1, &env->active_fpu.fp_status),
3274409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
3275409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(nge, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_lt(fst0, fst1, &env->active_fpu.fp_status),
3276409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_lt(fsth0, fsth1, &env->active_fpu.fp_status))
3277409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(le,  !float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)   && float32_le(fst0, fst1, &env->active_fpu.fp_status),
3278409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 !float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status) && float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
3279409c7b66435cf5947cab6bf0710f92507317f22eBhanu ChetlapalliFOP_COND_PS(ngt, float32_is_unordered(1, fst1, fst0, &env->active_fpu.fp_status)    || float32_le(fst0, fst1, &env->active_fpu.fp_status),
3280409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli                 float32_is_unordered(1, fsth1, fsth0, &env->active_fpu.fp_status)  || float32_le(fsth0, fsth1, &env->active_fpu.fp_status))
3281