2 * UniCore32 helper routines
4 * Copyright (C) 2010-2012 Guan Xuetao
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation, or (at your option) any
9 * later version. See the COPYING file in the top-level directory.
12 #include "dyngen-exec.h"
15 #define SIGNBIT (uint32_t)0x80000000
16 #define SIGNBIT64 ((uint64_t)1 << 63)
18 void HELPER(exception
)(uint32_t excp
)
20 env
->exception_index
= excp
;
24 static target_ulong
asr_read(void)
28 return env
->uncached_asr
| (env
->NF
& 0x80000000) | (ZF
<< 30) |
29 (env
->CF
<< 29) | ((env
->VF
& 0x80000000) >> 3);
32 target_ulong
cpu_asr_read(CPUUniCore32State
*env1
)
34 CPUUniCore32State
*saved_env
;
44 target_ulong
HELPER(asr_read
)(void)
49 static void asr_write(target_ulong val
, target_ulong mask
)
51 if (mask
& ASR_NZCV
) {
52 env
->ZF
= (~val
) & ASR_Z
;
54 env
->CF
= (val
>> 29) & 1;
55 env
->VF
= (val
<< 3) & 0x80000000;
58 if ((env
->uncached_asr
^ val
) & mask
& ASR_M
) {
59 switch_mode(env
, val
& ASR_M
);
62 env
->uncached_asr
= (env
->uncached_asr
& ~mask
) | (val
& mask
);
65 void cpu_asr_write(CPUUniCore32State
*env1
, target_ulong val
, target_ulong mask
)
67 CPUUniCore32State
*saved_env
;
75 void HELPER(asr_write
)(target_ulong val
, target_ulong mask
)
80 /* Access to user mode registers from privileged modes. */
81 uint32_t HELPER(get_user_reg
)(uint32_t regno
)
86 val
= env
->banked_r29
[0];
87 } else if (regno
== 30) {
88 val
= env
->banked_r30
[0];
90 val
= env
->regs
[regno
];
95 void HELPER(set_user_reg
)(uint32_t regno
, uint32_t val
)
98 env
->banked_r29
[0] = val
;
99 } else if (regno
== 30) {
100 env
->banked_r30
[0] = val
;
102 env
->regs
[regno
] = val
;
106 /* ??? Flag setting arithmetic is awkward because we need to do comparisons.
107 The only way to do that in TCG is a conditional branch, which clobbers
108 all our temporaries. For now implement these as helper functions. */
110 uint32_t HELPER(add_cc
)(uint32_t a
, uint32_t b
)
114 env
->NF
= env
->ZF
= result
;
115 env
->CF
= result
< a
;
116 env
->VF
= (a
^ b
^ -1) & (a
^ result
);
120 uint32_t HELPER(adc_cc
)(uint32_t a
, uint32_t b
)
125 env
->CF
= result
< a
;
128 env
->CF
= result
<= a
;
130 env
->VF
= (a
^ b
^ -1) & (a
^ result
);
131 env
->NF
= env
->ZF
= result
;
135 uint32_t HELPER(sub_cc
)(uint32_t a
, uint32_t b
)
139 env
->NF
= env
->ZF
= result
;
141 env
->VF
= (a
^ b
) & (a
^ result
);
145 uint32_t HELPER(sbc_cc
)(uint32_t a
, uint32_t b
)
155 env
->VF
= (a
^ b
) & (a
^ result
);
156 env
->NF
= env
->ZF
= result
;
160 /* Similarly for variable shift instructions. */
162 uint32_t HELPER(shl
)(uint32_t x
, uint32_t i
)
164 int shift
= i
& 0xff;
171 uint32_t HELPER(shr
)(uint32_t x
, uint32_t i
)
173 int shift
= i
& 0xff;
177 return (uint32_t)x
>> shift
;
180 uint32_t HELPER(sar
)(uint32_t x
, uint32_t i
)
182 int shift
= i
& 0xff;
186 return (int32_t)x
>> shift
;
189 uint32_t HELPER(shl_cc
)(uint32_t x
, uint32_t i
)
191 int shift
= i
& 0xff;
199 } else if (shift
!= 0) {
200 env
->CF
= (x
>> (32 - shift
)) & 1;
206 uint32_t HELPER(shr_cc
)(uint32_t x
, uint32_t i
)
208 int shift
= i
& 0xff;
211 env
->CF
= (x
>> 31) & 1;
216 } else if (shift
!= 0) {
217 env
->CF
= (x
>> (shift
- 1)) & 1;
223 uint32_t HELPER(sar_cc
)(uint32_t x
, uint32_t i
)
225 int shift
= i
& 0xff;
227 env
->CF
= (x
>> 31) & 1;
228 return (int32_t)x
>> 31;
229 } else if (shift
!= 0) {
230 env
->CF
= (x
>> (shift
- 1)) & 1;
231 return (int32_t)x
>> shift
;
236 uint32_t HELPER(ror_cc
)(uint32_t x
, uint32_t i
)
240 shift
= shift1
& 0x1f;
243 env
->CF
= (x
>> 31) & 1;
247 env
->CF
= (x
>> (shift
- 1)) & 1;
248 return ((uint32_t)x
>> shift
) | (x
<< (32 - shift
));
252 #ifndef CONFIG_USER_ONLY
253 #define MMUSUFFIX _mmu
256 #include "softmmu_template.h"
259 #include "softmmu_template.h"
262 #include "softmmu_template.h"
265 #include "softmmu_template.h"
267 void tlb_fill(CPUUniCore32State
*env1
, target_ulong addr
, int is_write
,
268 int mmu_idx
, uintptr_t retaddr
)
270 TranslationBlock
*tb
;
271 CPUUniCore32State
*saved_env
;
277 ret
= uc32_cpu_handle_mmu_fault(env
, addr
, is_write
, mmu_idx
);
280 /* now we have a real cpu fault */
281 pc
= (unsigned long)retaddr
;
283 if (tb
) {/* the PC is inside the translated code.
284 It means that we have a virtual CPU fault */
285 cpu_restore_state(tb
, env
, pc
);