Commit dceaf394585191ced65ce6a478580ac1655510d7
1 parent
069de562
CRIS: More TCG conversion.
* Convert moves to/from support function regs (including TLB updates) to TCG. * SCC no longer requires T0 to strictly be 0 or 1, relaxed to 0 or non-zero. * Convert the the condition code evaluation to TCG. * Convert rfe into a helper and TCG. * Convert evaluate_bcc and setf to TCG. * Convert clrf to TCG. * Convert CRIS exception raising to TCG. * Convert btst to TCG. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4376 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
332 additions
and
103 deletions
target-cris/helper.h
1 | 1 | #define TCG_HELPER_PROTO |
2 | -void TCG_HELPER_PROTO helper_tlb_update(uint32_t T0); | |
2 | + | |
3 | +void TCG_HELPER_PROTO helper_raise_exception(uint32_t index); | |
3 | 4 | void TCG_HELPER_PROTO helper_tlb_flush(void); |
4 | 5 | void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2); |
5 | 6 | void TCG_HELPER_PROTO helper_dummy(void); |
6 | 7 | void TCG_HELPER_PROTO helper_rfe(void); |
7 | 8 | void TCG_HELPER_PROTO helper_store(uint32_t a0); |
8 | 9 | |
10 | +void TCG_HELPER_PROTO helper_movl_sreg_reg (uint32_t sreg, uint32_t reg); | |
11 | +void TCG_HELPER_PROTO helper_movl_reg_sreg (uint32_t reg, uint32_t sreg); | |
12 | + | |
9 | 13 | void TCG_HELPER_PROTO helper_evaluate_flags_muls(void); |
10 | 14 | void TCG_HELPER_PROTO helper_evaluate_flags_mulu(void); |
11 | 15 | void TCG_HELPER_PROTO helper_evaluate_flags_mcp(void); | ... | ... |
target-cris/mmu.c
... | ... | @@ -265,7 +265,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, |
265 | 265 | } |
266 | 266 | |
267 | 267 | /* Give us the vaddr corresponding to the latest TLB update. */ |
268 | -target_ulong cris_mmu_tlb_latest_update(CPUState *env, uint32_t new_lo) | |
268 | +target_ulong cris_mmu_tlb_latest_update(CPUState *env) | |
269 | 269 | { |
270 | 270 | uint32_t sel = env->sregs[SFR_RW_MM_TLB_SEL]; |
271 | 271 | uint32_t vaddr; | ... | ... |
target-cris/mmu.h
... | ... | @@ -11,7 +11,7 @@ struct cris_mmu_result_t |
11 | 11 | int bf_vec; |
12 | 12 | }; |
13 | 13 | |
14 | -target_ulong cris_mmu_tlb_latest_update(CPUState *env, uint32_t new_lo); | |
14 | +target_ulong cris_mmu_tlb_latest_update(CPUState *env); | |
15 | 15 | int cris_mmu_translate(struct cris_mmu_result_t *res, |
16 | 16 | CPUState *env, uint32_t vaddr, |
17 | 17 | int rw, int mmu_idx); | ... | ... |
target-cris/op_helper.c
... | ... | @@ -79,20 +79,10 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) |
79 | 79 | env = saved_env; |
80 | 80 | } |
81 | 81 | |
82 | -void helper_tlb_update(uint32_t T0) | |
82 | +void helper_raise_exception(uint32_t index) | |
83 | 83 | { |
84 | -#if !defined(CONFIG_USER_ONLY) | |
85 | - uint32_t vaddr; | |
86 | - uint32_t srs = env->pregs[PR_SRS]; | |
87 | - | |
88 | - if (srs != 1 && srs != 2) | |
89 | - return; | |
90 | - | |
91 | - vaddr = cris_mmu_tlb_latest_update(env, T0); | |
92 | - D(fprintf(logfile, "flush old_vaddr=%x vaddr=%x T0=%x\n", vaddr, | |
93 | - env->sregs[SFR_R_MM_CAUSE] & TARGET_PAGE_MASK, T0)); | |
94 | - tlb_flush_page(env, vaddr); | |
95 | -#endif | |
84 | + env->exception_index = index; | |
85 | + cpu_loop_exit(); | |
96 | 86 | } |
97 | 87 | |
98 | 88 | void helper_tlb_flush(void) |
... | ... | @@ -110,13 +100,105 @@ void helper_dummy(void) |
110 | 100 | |
111 | 101 | } |
112 | 102 | |
113 | -/* Only used for debugging at the moment. */ | |
103 | +void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg) | |
104 | +{ | |
105 | + uint32_t srs; | |
106 | + srs = env->pregs[PR_SRS]; | |
107 | + srs &= 3; | |
108 | + env->sregs[srs][sreg] = env->regs[reg]; | |
109 | + | |
110 | +#if !defined(CONFIG_USER_ONLY) | |
111 | + if (srs == 1 || srs == 2) { | |
112 | + if (sreg == 6) { | |
113 | + /* Writes to tlb-hi write to mm_cause as a side | |
114 | + effect. */ | |
115 | + env->sregs[SFR_RW_MM_TLB_HI] = T0; | |
116 | + env->sregs[SFR_R_MM_CAUSE] = T0; | |
117 | + } | |
118 | + else if (sreg == 5) { | |
119 | + uint32_t set; | |
120 | + uint32_t idx; | |
121 | + uint32_t lo, hi; | |
122 | + uint32_t vaddr; | |
123 | + | |
124 | + vaddr = cris_mmu_tlb_latest_update(env); | |
125 | + D(fprintf(logfile, "tlb flush vaddr=%x\n", vaddr)); | |
126 | + tlb_flush_page(env, vaddr); | |
127 | + | |
128 | + idx = set = env->sregs[SFR_RW_MM_TLB_SEL]; | |
129 | + set >>= 4; | |
130 | + set &= 3; | |
131 | + | |
132 | + idx &= 15; | |
133 | + /* We've just made a write to tlb_lo. */ | |
134 | + lo = env->sregs[SFR_RW_MM_TLB_LO]; | |
135 | + /* Writes are done via r_mm_cause. */ | |
136 | + hi = env->sregs[SFR_R_MM_CAUSE]; | |
137 | + env->tlbsets[srs - 1][set][idx].lo = lo; | |
138 | + env->tlbsets[srs - 1][set][idx].hi = hi; | |
139 | + } | |
140 | + } | |
141 | +#endif | |
142 | +} | |
143 | + | |
144 | +void helper_movl_reg_sreg (uint32_t reg, uint32_t sreg) | |
145 | +{ | |
146 | + uint32_t srs; | |
147 | + env->pregs[PR_SRS] &= 3; | |
148 | + srs = env->pregs[PR_SRS]; | |
149 | + | |
150 | +#if !defined(CONFIG_USER_ONLY) | |
151 | + if (srs == 1 || srs == 2) | |
152 | + { | |
153 | + uint32_t set; | |
154 | + uint32_t idx; | |
155 | + uint32_t lo, hi; | |
156 | + | |
157 | + idx = set = env->sregs[SFR_RW_MM_TLB_SEL]; | |
158 | + set >>= 4; | |
159 | + set &= 3; | |
160 | + idx &= 15; | |
161 | + | |
162 | + /* Update the mirror regs. */ | |
163 | + hi = env->tlbsets[srs - 1][set][idx].hi; | |
164 | + lo = env->tlbsets[srs - 1][set][idx].lo; | |
165 | + env->sregs[SFR_RW_MM_TLB_HI] = hi; | |
166 | + env->sregs[SFR_RW_MM_TLB_LO] = lo; | |
167 | + } | |
168 | +#endif | |
169 | + env->regs[reg] = env->sregs[srs][sreg]; | |
170 | + RETURN(); | |
171 | +} | |
172 | + | |
173 | +static void cris_ccs_rshift(CPUState *env) | |
174 | +{ | |
175 | + uint32_t ccs; | |
176 | + | |
177 | + /* Apply the ccs shift. */ | |
178 | + ccs = env->pregs[PR_CCS]; | |
179 | + ccs = (ccs & 0xc0000000) | ((ccs & 0x0fffffff) >> 10); | |
180 | + if (ccs & U_FLAG) | |
181 | + { | |
182 | + /* Enter user mode. */ | |
183 | + env->ksp = env->regs[R_SP]; | |
184 | + env->regs[R_SP] = env->pregs[PR_USP]; | |
185 | + } | |
186 | + | |
187 | + env->pregs[PR_CCS] = ccs; | |
188 | +} | |
189 | + | |
114 | 190 | void helper_rfe(void) |
115 | 191 | { |
116 | 192 | D(fprintf(logfile, "rfe: erp=%x pid=%x ccs=%x btarget=%x\n", |
117 | 193 | env->pregs[PR_ERP], env->pregs[PR_PID], |
118 | 194 | env->pregs[PR_CCS], |
119 | 195 | env->btarget)); |
196 | + | |
197 | + cris_ccs_rshift(env); | |
198 | + | |
199 | + /* RFE sets the P_FLAG only if the R_FLAG is not set. */ | |
200 | + if (!(env->pregs[PR_CCS] & R_FLAG)) | |
201 | + env->pregs[PR_CCS] |= P_FLAG; | |
120 | 202 | } |
121 | 203 | |
122 | 204 | void helper_store(uint32_t a0) |
... | ... | @@ -155,7 +237,6 @@ static void evaluate_flags_writeback(uint32_t flags) |
155 | 237 | env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG); |
156 | 238 | flags &= env->cc_mask; |
157 | 239 | env->pregs[PR_CCS] |= flags; |
158 | - RETURN(); | |
159 | 240 | } |
160 | 241 | |
161 | 242 | void helper_evaluate_flags_muls(void) |
... | ... | @@ -164,8 +245,7 @@ void helper_evaluate_flags_muls(void) |
164 | 245 | uint32_t dst; |
165 | 246 | uint32_t res; |
166 | 247 | uint32_t flags = 0; |
167 | - /* were gonna have to redo the muls. */ | |
168 | - int64_t tmp, t0 ,t1; | |
248 | + int64_t tmp; | |
169 | 249 | int32_t mof; |
170 | 250 | int dneg; |
171 | 251 | |
... | ... | @@ -173,14 +253,12 @@ void helper_evaluate_flags_muls(void) |
173 | 253 | dst = env->cc_dest; |
174 | 254 | res = env->cc_result; |
175 | 255 | |
176 | - | |
177 | - /* cast into signed values to make GCC sign extend. */ | |
178 | - t0 = (int32_t)src; | |
179 | - t1 = (int32_t)dst; | |
180 | 256 | dneg = ((int32_t)res) < 0; |
181 | 257 | |
182 | - tmp = t0 * t1; | |
183 | - mof = tmp >> 32; | |
258 | + mof = env->pregs[PR_MOF]; | |
259 | + tmp = mof; | |
260 | + tmp <<= 32; | |
261 | + tmp |= res; | |
184 | 262 | if (tmp == 0) |
185 | 263 | flags |= Z_FLAG; |
186 | 264 | else if (tmp < 0) |
... | ... | @@ -197,21 +275,17 @@ void helper_evaluate_flags_mulu(void) |
197 | 275 | uint32_t dst; |
198 | 276 | uint32_t res; |
199 | 277 | uint32_t flags = 0; |
200 | - /* were gonna have to redo the muls. */ | |
201 | - uint64_t tmp, t0 ,t1; | |
278 | + uint64_t tmp; | |
202 | 279 | uint32_t mof; |
203 | 280 | |
204 | 281 | src = env->cc_src; |
205 | 282 | dst = env->cc_dest; |
206 | 283 | res = env->cc_result; |
207 | 284 | |
208 | - | |
209 | - /* cast into signed values to make GCC sign extend. */ | |
210 | - t0 = src; | |
211 | - t1 = dst; | |
212 | - | |
213 | - tmp = t0 * t1; | |
214 | - mof = tmp >> 32; | |
285 | + mof = env->pregs[PR_MOF]; | |
286 | + tmp = mof; | |
287 | + tmp <<= 32; | |
288 | + tmp |= res; | |
215 | 289 | if (tmp == 0) |
216 | 290 | flags |= Z_FLAG; |
217 | 291 | else if (tmp >> 63) | ... | ... |
target-cris/translate.c
... | ... | @@ -223,9 +223,9 @@ static inline void t_gen_mov_preg_TN(int r, TCGv tn) |
223 | 223 | } |
224 | 224 | } |
225 | 225 | |
226 | -static inline void t_gen_mov_TN_im(TCGv tn, int32_t val) | |
226 | +static inline void t_gen_raise_exception(uint32_t index) | |
227 | 227 | { |
228 | - tcg_gen_movi_tl(tn, val); | |
228 | + tcg_gen_helper_0_1(helper_raise_exception, tcg_const_tl(index)); | |
229 | 229 | } |
230 | 230 | |
231 | 231 | static void t_gen_lsl(TCGv d, TCGv a, TCGv b) |
... | ... | @@ -375,6 +375,62 @@ static void t_gen_lz_i32(TCGv d, TCGv x) |
375 | 375 | tcg_gen_discard_i32(n); |
376 | 376 | } |
377 | 377 | |
378 | +static void t_gen_btst(TCGv d, TCGv s) | |
379 | +{ | |
380 | + TCGv sbit; | |
381 | + TCGv bset; | |
382 | + int l1; | |
383 | + | |
384 | + /* des ref: | |
385 | + The N flag is set according to the selected bit in the dest reg. | |
386 | + The Z flag is set if the selected bit and all bits to the right are | |
387 | + zero. | |
388 | + The X flag is cleared. | |
389 | + Other flags are left untouched. | |
390 | + The destination reg is not affected. | |
391 | + | |
392 | + unsigned int fz, sbit, bset, mask, masked_t0; | |
393 | + | |
394 | + sbit = T1 & 31; | |
395 | + bset = !!(T0 & (1 << sbit)); | |
396 | + mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1; | |
397 | + masked_t0 = T0 & mask; | |
398 | + fz = !(masked_t0 | bset); | |
399 | + | |
400 | + // Clear the X, N and Z flags. | |
401 | + T0 = env->pregs[PR_CCS] & ~(X_FLAG | N_FLAG | Z_FLAG); | |
402 | + // Set the N and Z flags accordingly. | |
403 | + T0 |= (bset << 3) | (fz << 2); | |
404 | + */ | |
405 | + | |
406 | + l1 = gen_new_label(); | |
407 | + sbit = tcg_temp_new(TCG_TYPE_TL); | |
408 | + bset = tcg_temp_new(TCG_TYPE_TL); | |
409 | + | |
410 | + /* Compute bset and sbit. */ | |
411 | + tcg_gen_andi_tl(sbit, s, 31); | |
412 | + tcg_gen_shl_tl(s, tcg_const_tl(1), sbit); | |
413 | + tcg_gen_and_tl(bset, d, s); | |
414 | + tcg_gen_shr_tl(bset, bset, sbit); | |
415 | + /* Displace to N_FLAG. */ | |
416 | + tcg_gen_shli_tl(bset, bset, 3); | |
417 | + | |
418 | + tcg_gen_shl_tl(sbit, tcg_const_tl(2), sbit); | |
419 | + tcg_gen_subi_tl(sbit, sbit, 1); | |
420 | + tcg_gen_and_tl(sbit, d, sbit); | |
421 | + | |
422 | + tcg_gen_andi_tl(d, cpu_PR[PR_CCS], ~(X_FLAG | N_FLAG | Z_FLAG)); | |
423 | + /* or in the N_FLAG. */ | |
424 | + tcg_gen_or_tl(d, d, bset); | |
425 | + tcg_gen_brcond_tl(TCG_COND_NE, sbit, tcg_const_tl(0), l1); | |
426 | + /* or in the Z_FLAG. */ | |
427 | + tcg_gen_ori_tl(d, d, Z_FLAG); | |
428 | + gen_set_label(l1); | |
429 | + | |
430 | + tcg_gen_discard_tl(sbit); | |
431 | + tcg_gen_discard_tl(bset); | |
432 | +} | |
433 | + | |
378 | 434 | static void t_gen_cris_dstep(TCGv d, TCGv s) |
379 | 435 | { |
380 | 436 | int l1; |
... | ... | @@ -738,7 +794,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) |
738 | 794 | t_gen_lz_i32(cpu_T[0], cpu_T[1]); |
739 | 795 | break; |
740 | 796 | case CC_OP_BTST: |
741 | - gen_op_btst_T0_T1(); | |
797 | + t_gen_btst(cpu_T[0], cpu_T[1]); | |
742 | 798 | writeback = 0; |
743 | 799 | break; |
744 | 800 | case CC_OP_MULS: |
... | ... | @@ -846,83 +902,172 @@ static void gen_tst_cc (DisasContext *dc, int cond) |
846 | 902 | int arith_opt; |
847 | 903 | |
848 | 904 | /* TODO: optimize more condition codes. */ |
905 | + | |
906 | + /* | |
907 | + * If the flags are live, we've gotta look into the bits of CCS. | |
908 | + * Otherwise, if we just did an arithmetic operation we try to | |
909 | + * evaluate the condition code faster. | |
910 | + * | |
911 | + * When this function is done, T0 should be non-zero if the condition | |
912 | + * code is true. | |
913 | + */ | |
849 | 914 | arith_opt = arith_cc(dc) && !dc->flags_live; |
850 | 915 | switch (cond) { |
851 | 916 | case CC_EQ: |
852 | - if (arith_opt) | |
853 | - gen_op_tst_cc_eq_fast (); | |
917 | + if (arith_opt) { | |
918 | + /* If cc_result is zero, T0 should be | |
919 | + non-zero otherwise T0 should be zero. */ | |
920 | + int l1; | |
921 | + l1 = gen_new_label(); | |
922 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
923 | + tcg_gen_brcond_tl(TCG_COND_NE, cc_result, | |
924 | + tcg_const_tl(0), l1); | |
925 | + tcg_gen_movi_tl(cpu_T[0], 1); | |
926 | + gen_set_label(l1); | |
927 | + } | |
854 | 928 | else { |
855 | 929 | cris_evaluate_flags(dc); |
856 | - gen_op_tst_cc_eq (); | |
930 | + tcg_gen_andi_tl(cpu_T[0], | |
931 | + cpu_PR[PR_CCS], Z_FLAG); | |
857 | 932 | } |
858 | 933 | break; |
859 | 934 | case CC_NE: |
860 | 935 | if (arith_opt) |
861 | - gen_op_tst_cc_ne_fast (); | |
936 | + tcg_gen_mov_tl(cpu_T[0], cc_result); | |
862 | 937 | else { |
863 | 938 | cris_evaluate_flags(dc); |
864 | - gen_op_tst_cc_ne (); | |
939 | + tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS], | |
940 | + Z_FLAG); | |
941 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], Z_FLAG); | |
865 | 942 | } |
866 | 943 | break; |
867 | 944 | case CC_CS: |
868 | 945 | cris_evaluate_flags(dc); |
869 | - gen_op_tst_cc_cs (); | |
946 | + tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], C_FLAG); | |
870 | 947 | break; |
871 | 948 | case CC_CC: |
872 | 949 | cris_evaluate_flags(dc); |
873 | - gen_op_tst_cc_cc (); | |
950 | + tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS], | |
951 | + C_FLAG); | |
952 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], C_FLAG); | |
874 | 953 | break; |
875 | 954 | case CC_VS: |
876 | 955 | cris_evaluate_flags(dc); |
877 | - gen_op_tst_cc_vs (); | |
956 | + tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], V_FLAG); | |
878 | 957 | break; |
879 | 958 | case CC_VC: |
880 | 959 | cris_evaluate_flags(dc); |
881 | - gen_op_tst_cc_vc (); | |
960 | + tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS], | |
961 | + V_FLAG); | |
962 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], V_FLAG); | |
882 | 963 | break; |
883 | 964 | case CC_PL: |
884 | 965 | if (arith_opt) |
885 | - gen_op_tst_cc_pl_fast (); | |
966 | + tcg_gen_shli_tl(cpu_T[0], cc_result, 31); | |
886 | 967 | else { |
887 | 968 | cris_evaluate_flags(dc); |
888 | - gen_op_tst_cc_pl (); | |
969 | + tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS], | |
970 | + N_FLAG); | |
971 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG); | |
889 | 972 | } |
890 | 973 | break; |
891 | 974 | case CC_MI: |
892 | - if (arith_opt) | |
893 | - gen_op_tst_cc_mi_fast (); | |
975 | + if (arith_opt) { | |
976 | + tcg_gen_shli_tl(cpu_T[0], cc_result, 31); | |
977 | + tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1); | |
978 | + } | |
894 | 979 | else { |
895 | 980 | cris_evaluate_flags(dc); |
896 | - gen_op_tst_cc_mi (); | |
981 | + tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], | |
982 | + N_FLAG); | |
897 | 983 | } |
898 | 984 | break; |
899 | 985 | case CC_LS: |
900 | 986 | cris_evaluate_flags(dc); |
901 | - gen_op_tst_cc_ls (); | |
987 | + tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], | |
988 | + C_FLAG | Z_FLAG); | |
902 | 989 | break; |
903 | 990 | case CC_HI: |
904 | 991 | cris_evaluate_flags(dc); |
905 | - gen_op_tst_cc_hi (); | |
992 | + { | |
993 | + TCGv tmp; | |
994 | + | |
995 | + tmp = tcg_temp_new(TCG_TYPE_TL); | |
996 | + tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS], | |
997 | + C_FLAG | Z_FLAG); | |
998 | + /* Overlay the C flag on top of the Z. */ | |
999 | + tcg_gen_shli_tl(cpu_T[0], tmp, 2); | |
1000 | + tcg_gen_and_tl(cpu_T[0], tmp, cpu_T[0]); | |
1001 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], Z_FLAG); | |
1002 | + | |
1003 | + tcg_gen_discard_tl(tmp); | |
1004 | + } | |
906 | 1005 | break; |
907 | 1006 | case CC_GE: |
908 | 1007 | cris_evaluate_flags(dc); |
909 | - gen_op_tst_cc_ge (); | |
1008 | + /* Overlay the V flag on top of the N. */ | |
1009 | + tcg_gen_shli_tl(cpu_T[0], cpu_PR[PR_CCS], 2); | |
1010 | + tcg_gen_xor_tl(cpu_T[0], | |
1011 | + cpu_PR[PR_CCS], cpu_T[0]); | |
1012 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG); | |
1013 | + tcg_gen_xori_tl(cpu_T[0], cpu_T[0], N_FLAG); | |
910 | 1014 | break; |
911 | 1015 | case CC_LT: |
912 | 1016 | cris_evaluate_flags(dc); |
913 | - gen_op_tst_cc_lt (); | |
1017 | + /* Overlay the V flag on top of the N. */ | |
1018 | + tcg_gen_shli_tl(cpu_T[0], cpu_PR[PR_CCS], 2); | |
1019 | + tcg_gen_xor_tl(cpu_T[0], | |
1020 | + cpu_PR[PR_CCS], cpu_T[0]); | |
1021 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], N_FLAG); | |
914 | 1022 | break; |
915 | 1023 | case CC_GT: |
916 | 1024 | cris_evaluate_flags(dc); |
917 | - gen_op_tst_cc_gt (); | |
1025 | + { | |
1026 | + TCGv n, z; | |
1027 | + | |
1028 | + n = tcg_temp_new(TCG_TYPE_TL); | |
1029 | + z = tcg_temp_new(TCG_TYPE_TL); | |
1030 | + | |
1031 | + /* To avoid a shift we overlay everything on | |
1032 | + the V flag. */ | |
1033 | + tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2); | |
1034 | + tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1); | |
1035 | + /* invert Z. */ | |
1036 | + tcg_gen_xori_tl(z, z, 2); | |
1037 | + | |
1038 | + tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]); | |
1039 | + tcg_gen_xori_tl(n, n, 2); | |
1040 | + tcg_gen_and_tl(cpu_T[0], z, n); | |
1041 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 2); | |
1042 | + | |
1043 | + tcg_gen_discard_tl(n); | |
1044 | + tcg_gen_discard_tl(z); | |
1045 | + } | |
918 | 1046 | break; |
919 | 1047 | case CC_LE: |
920 | 1048 | cris_evaluate_flags(dc); |
921 | - gen_op_tst_cc_le (); | |
1049 | + { | |
1050 | + TCGv n, z; | |
1051 | + | |
1052 | + n = tcg_temp_new(TCG_TYPE_TL); | |
1053 | + z = tcg_temp_new(TCG_TYPE_TL); | |
1054 | + | |
1055 | + /* To avoid a shift we overlay everything on | |
1056 | + the V flag. */ | |
1057 | + tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2); | |
1058 | + tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1); | |
1059 | + | |
1060 | + tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]); | |
1061 | + tcg_gen_or_tl(cpu_T[0], z, n); | |
1062 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 2); | |
1063 | + | |
1064 | + tcg_gen_discard_tl(n); | |
1065 | + tcg_gen_discard_tl(z); | |
1066 | + } | |
922 | 1067 | break; |
923 | 1068 | case CC_P: |
924 | 1069 | cris_evaluate_flags(dc); |
925 | - gen_op_tst_cc_p (); | |
1070 | + tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], P_FLAG); | |
926 | 1071 | break; |
927 | 1072 | case CC_A: |
928 | 1073 | cris_evaluate_flags(dc); |
... | ... | @@ -944,7 +1089,7 @@ static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond) |
944 | 1089 | if (cond != CC_A) |
945 | 1090 | { |
946 | 1091 | gen_tst_cc (dc, cond); |
947 | - gen_op_evaluate_bcc (); | |
1092 | + t_gen_mov_env_TN(btaken, cpu_T[0]); | |
948 | 1093 | } |
949 | 1094 | tcg_gen_movi_tl(env_btarget, dc->delayed_pc); |
950 | 1095 | } |
... | ... | @@ -1225,7 +1370,7 @@ static unsigned int dec_subq(DisasContext *dc) |
1225 | 1370 | cris_cc_mask(dc, CC_MASK_NZVC); |
1226 | 1371 | /* Fetch register operand, */ |
1227 | 1372 | t_gen_mov_TN_reg(cpu_T[0], dc->op2); |
1228 | - t_gen_mov_TN_im(cpu_T[1], dc->op1); | |
1373 | + tcg_gen_movi_tl(cpu_T[1], dc->op1); | |
1229 | 1374 | crisv32_alu_op(dc, CC_OP_SUB, dc->op2, 4); |
1230 | 1375 | return 2; |
1231 | 1376 | } |
... | ... | @@ -1238,7 +1383,7 @@ static unsigned int dec_cmpq(DisasContext *dc) |
1238 | 1383 | DIS(fprintf (logfile, "cmpq %d, $r%d\n", imm, dc->op2)); |
1239 | 1384 | cris_cc_mask(dc, CC_MASK_NZVC); |
1240 | 1385 | t_gen_mov_TN_reg(cpu_T[0], dc->op2); |
1241 | - t_gen_mov_TN_im(cpu_T[1], imm); | |
1386 | + tcg_gen_movi_tl(cpu_T[1], imm); | |
1242 | 1387 | crisv32_alu_op(dc, CC_OP_CMP, dc->op2, 4); |
1243 | 1388 | return 2; |
1244 | 1389 | } |
... | ... | @@ -1251,7 +1396,7 @@ static unsigned int dec_andq(DisasContext *dc) |
1251 | 1396 | DIS(fprintf (logfile, "andq %d, $r%d\n", imm, dc->op2)); |
1252 | 1397 | cris_cc_mask(dc, CC_MASK_NZ); |
1253 | 1398 | t_gen_mov_TN_reg(cpu_T[0], dc->op2); |
1254 | - t_gen_mov_TN_im(cpu_T[1], imm); | |
1399 | + tcg_gen_movi_tl(cpu_T[1], imm); | |
1255 | 1400 | crisv32_alu_op(dc, CC_OP_AND, dc->op2, 4); |
1256 | 1401 | return 2; |
1257 | 1402 | } |
... | ... | @@ -1263,7 +1408,7 @@ static unsigned int dec_orq(DisasContext *dc) |
1263 | 1408 | DIS(fprintf (logfile, "orq %d, $r%d\n", imm, dc->op2)); |
1264 | 1409 | cris_cc_mask(dc, CC_MASK_NZ); |
1265 | 1410 | t_gen_mov_TN_reg(cpu_T[0], dc->op2); |
1266 | - t_gen_mov_TN_im(cpu_T[1], imm); | |
1411 | + tcg_gen_movi_tl(cpu_T[1], imm); | |
1267 | 1412 | crisv32_alu_op(dc, CC_OP_OR, dc->op2, 4); |
1268 | 1413 | return 2; |
1269 | 1414 | } |
... | ... | @@ -1272,10 +1417,9 @@ static unsigned int dec_btstq(DisasContext *dc) |
1272 | 1417 | dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4); |
1273 | 1418 | DIS(fprintf (logfile, "btstq %u, $r%d\n", dc->op1, dc->op2)); |
1274 | 1419 | |
1275 | - cris_evaluate_flags(dc); | |
1276 | 1420 | cris_cc_mask(dc, CC_MASK_NZ); |
1277 | 1421 | t_gen_mov_TN_reg(cpu_T[0], dc->op2); |
1278 | - t_gen_mov_TN_im(cpu_T[1], dc->op1); | |
1422 | + tcg_gen_movi_tl(cpu_T[1], dc->op1); | |
1279 | 1423 | crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4); |
1280 | 1424 | |
1281 | 1425 | cris_update_cc_op(dc, CC_OP_FLAGS, 4); |
... | ... | @@ -1289,7 +1433,7 @@ static unsigned int dec_asrq(DisasContext *dc) |
1289 | 1433 | DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2)); |
1290 | 1434 | cris_cc_mask(dc, CC_MASK_NZ); |
1291 | 1435 | t_gen_mov_TN_reg(cpu_T[0], dc->op2); |
1292 | - t_gen_mov_TN_im(cpu_T[1], dc->op1); | |
1436 | + tcg_gen_movi_tl(cpu_T[1], dc->op1); | |
1293 | 1437 | crisv32_alu_op(dc, CC_OP_ASR, dc->op2, 4); |
1294 | 1438 | return 2; |
1295 | 1439 | } |
... | ... | @@ -1300,7 +1444,7 @@ static unsigned int dec_lslq(DisasContext *dc) |
1300 | 1444 | |
1301 | 1445 | cris_cc_mask(dc, CC_MASK_NZ); |
1302 | 1446 | t_gen_mov_TN_reg(cpu_T[0], dc->op2); |
1303 | - t_gen_mov_TN_im(cpu_T[1], dc->op1); | |
1447 | + tcg_gen_movi_tl(cpu_T[1], dc->op1); | |
1304 | 1448 | crisv32_alu_op(dc, CC_OP_LSL, dc->op2, 4); |
1305 | 1449 | return 2; |
1306 | 1450 | } |
... | ... | @@ -1311,7 +1455,7 @@ static unsigned int dec_lsrq(DisasContext *dc) |
1311 | 1455 | |
1312 | 1456 | cris_cc_mask(dc, CC_MASK_NZ); |
1313 | 1457 | t_gen_mov_TN_reg(cpu_T[0], dc->op2); |
1314 | - t_gen_mov_TN_im(cpu_T[1], dc->op1); | |
1458 | + tcg_gen_movi_tl(cpu_T[1], dc->op1); | |
1315 | 1459 | crisv32_alu_op(dc, CC_OP_LSR, dc->op2, 4); |
1316 | 1460 | return 2; |
1317 | 1461 | } |
... | ... | @@ -1338,14 +1482,20 @@ static unsigned int dec_scc_r(DisasContext *dc) |
1338 | 1482 | |
1339 | 1483 | if (cond != CC_A) |
1340 | 1484 | { |
1485 | + int l1; | |
1486 | + | |
1341 | 1487 | gen_tst_cc (dc, cond); |
1342 | - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); | |
1488 | + | |
1489 | + l1 = gen_new_label(); | |
1490 | + tcg_gen_movi_tl(cpu_R[dc->op1], 0); | |
1491 | + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), l1); | |
1492 | + tcg_gen_movi_tl(cpu_R[dc->op1], 1); | |
1493 | + gen_set_label(l1); | |
1343 | 1494 | } |
1344 | 1495 | else |
1345 | - tcg_gen_movi_tl(cpu_T[1], 1); | |
1496 | + tcg_gen_movi_tl(cpu_R[dc->op1], 1); | |
1346 | 1497 | |
1347 | 1498 | cris_cc_mask(dc, 0); |
1348 | - crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4); | |
1349 | 1499 | return 2; |
1350 | 1500 | } |
1351 | 1501 | |
... | ... | @@ -1624,7 +1774,6 @@ static unsigned int dec_btst_r(DisasContext *dc) |
1624 | 1774 | { |
1625 | 1775 | DIS(fprintf (logfile, "btst $r%u, $r%u\n", |
1626 | 1776 | dc->op1, dc->op2)); |
1627 | - cris_evaluate_flags(dc); | |
1628 | 1777 | cris_cc_mask(dc, CC_MASK_NZ); |
1629 | 1778 | dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); |
1630 | 1779 | crisv32_alu_op(dc, CC_OP_BTST, dc->op2, 4); |
... | ... | @@ -1772,10 +1921,18 @@ static unsigned int dec_setclrf(DisasContext *dc) |
1772 | 1921 | cris_update_cc_op(dc, CC_OP_FLAGS, 4); |
1773 | 1922 | tcg_gen_movi_tl(cc_op, dc->cc_op); |
1774 | 1923 | |
1775 | - if (set) | |
1776 | - gen_op_setf(flags); | |
1924 | + if (set) { | |
1925 | + if (!dc->user && (flags & U_FLAG)) { | |
1926 | + /* Enter user mode. */ | |
1927 | + t_gen_mov_env_TN(ksp, cpu_R[R_SP]); | |
1928 | + tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]); | |
1929 | + dc->is_jmp = DISAS_UPDATE; | |
1930 | + } | |
1931 | + tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags); | |
1932 | + } | |
1777 | 1933 | else |
1778 | - gen_op_clrf(flags); | |
1934 | + tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags); | |
1935 | + | |
1779 | 1936 | dc->flags_live = 1; |
1780 | 1937 | dc->clear_x = 0; |
1781 | 1938 | return 2; |
... | ... | @@ -1785,28 +1942,19 @@ static unsigned int dec_move_rs(DisasContext *dc) |
1785 | 1942 | { |
1786 | 1943 | DIS(fprintf (logfile, "move $r%u, $s%u\n", dc->op1, dc->op2)); |
1787 | 1944 | cris_cc_mask(dc, 0); |
1788 | - t_gen_mov_TN_reg(cpu_T[0], dc->op1); | |
1789 | - gen_op_movl_sreg_T0(dc->op2); | |
1790 | - | |
1791 | -#if !defined(CONFIG_USER_ONLY) | |
1792 | - if (dc->op2 == 6) | |
1793 | - gen_op_movl_tlb_hi_T0(); | |
1794 | - else if (dc->op2 == 5) { /* srs is checked at runtime. */ | |
1795 | - tcg_gen_helper_0_1(helper_tlb_update, cpu_T[0]); | |
1796 | - gen_op_movl_tlb_lo_T0(); | |
1797 | - } | |
1798 | -#endif | |
1945 | + tcg_gen_helper_0_2(helper_movl_sreg_reg, | |
1946 | + tcg_const_tl(dc->op2), tcg_const_tl(dc->op1)); | |
1799 | 1947 | return 2; |
1800 | 1948 | } |
1801 | 1949 | static unsigned int dec_move_sr(DisasContext *dc) |
1802 | 1950 | { |
1803 | 1951 | DIS(fprintf (logfile, "move $s%u, $r%u\n", dc->op2, dc->op1)); |
1804 | 1952 | cris_cc_mask(dc, 0); |
1805 | - gen_op_movl_T0_sreg(dc->op2); | |
1806 | - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); | |
1807 | - crisv32_alu_op(dc, CC_OP_MOVE, dc->op1, 4); | |
1953 | + tcg_gen_helper_0_2(helper_movl_reg_sreg, | |
1954 | + tcg_const_tl(dc->op1), tcg_const_tl(dc->op2)); | |
1808 | 1955 | return 2; |
1809 | 1956 | } |
1957 | + | |
1810 | 1958 | static unsigned int dec_move_rp(DisasContext *dc) |
1811 | 1959 | { |
1812 | 1960 | DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2)); |
... | ... | @@ -2024,9 +2172,11 @@ static unsigned int dec_test_m(DisasContext *dc) |
2024 | 2172 | dc->op1, dc->postinc ? "+]" : "]", |
2025 | 2173 | dc->op2)); |
2026 | 2174 | |
2175 | + cris_evaluate_flags(dc); | |
2176 | + | |
2027 | 2177 | insn_len = dec_prep_alu_m(dc, 0, memsize); |
2028 | 2178 | cris_cc_mask(dc, CC_MASK_NZ); |
2029 | - gen_op_clrf(3); | |
2179 | + tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3); | |
2030 | 2180 | |
2031 | 2181 | tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); |
2032 | 2182 | tcg_gen_movi_tl(cpu_T[1], 0); |
... | ... | @@ -2444,10 +2594,6 @@ static unsigned int dec_rfe_etc(DisasContext *dc) |
2444 | 2594 | case 2: |
2445 | 2595 | /* rfe. */ |
2446 | 2596 | cris_evaluate_flags(dc); |
2447 | - gen_op_ccs_rshift(); | |
2448 | - /* FIXME: don't set the P-FLAG if R is set. */ | |
2449 | - tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], P_FLAG); | |
2450 | - /* Debug helper. */ | |
2451 | 2597 | tcg_gen_helper_0_0(helper_rfe); |
2452 | 2598 | dc->is_jmp = DISAS_UPDATE; |
2453 | 2599 | break; |
... | ... | @@ -2460,7 +2606,9 @@ static unsigned int dec_rfe_etc(DisasContext *dc) |
2460 | 2606 | tcg_gen_movi_tl(cpu_T[0], dc->pc); |
2461 | 2607 | t_gen_mov_env_TN(pc, cpu_T[0]); |
2462 | 2608 | /* Breaks start at 16 in the exception vector. */ |
2463 | - gen_op_break_im(dc->op1 + 16); | |
2609 | + t_gen_mov_env_TN(trap_vector, | |
2610 | + tcg_const_tl(dc->op1 + 16)); | |
2611 | + t_gen_raise_exception(EXCP_BREAK); | |
2464 | 2612 | dc->is_jmp = DISAS_UPDATE; |
2465 | 2613 | break; |
2466 | 2614 | default: |
... | ... | @@ -2642,7 +2790,7 @@ static void check_breakpoint(CPUState *env, DisasContext *dc) |
2642 | 2790 | cris_evaluate_flags (dc); |
2643 | 2791 | tcg_gen_movi_tl(cpu_T[0], dc->pc); |
2644 | 2792 | t_gen_mov_env_TN(pc, cpu_T[0]); |
2645 | - gen_op_debug(); | |
2793 | + t_gen_raise_exception(EXCP_DEBUG); | |
2646 | 2794 | dc->is_jmp = DISAS_UPDATE; |
2647 | 2795 | } |
2648 | 2796 | } |
... | ... | @@ -2689,13 +2837,14 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, |
2689 | 2837 | |
2690 | 2838 | if (loglevel & CPU_LOG_TB_IN_ASM) { |
2691 | 2839 | fprintf(logfile, |
2692 | - "search=%d pc=%x ccs=%x pid=%x usp=%x\n" | |
2840 | + "search=%d pc=%x ccs=%x pid=%x usp=%x dbg=%x %x %x\n" | |
2693 | 2841 | "%x.%x.%x.%x\n" |
2694 | 2842 | "%x.%x.%x.%x\n" |
2695 | 2843 | "%x.%x.%x.%x\n" |
2696 | 2844 | "%x.%x.%x.%x\n", |
2697 | 2845 | search_pc, env->pc, env->pregs[PR_CCS], |
2698 | 2846 | env->pregs[PR_PID], env->pregs[PR_USP], |
2847 | + env->debug1, env->debug2, env->debug3, | |
2699 | 2848 | env->regs[0], env->regs[1], env->regs[2], env->regs[3], |
2700 | 2849 | env->regs[4], env->regs[5], env->regs[6], env->regs[7], |
2701 | 2850 | env->regs[8], env->regs[9], |
... | ... | @@ -2733,7 +2882,6 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, |
2733 | 2882 | |
2734 | 2883 | dc->clear_x = 1; |
2735 | 2884 | insn_len = cris_decoder(dc); |
2736 | - STATS(gen_op_exec_insn()); | |
2737 | 2885 | dc->ppc = dc->pc; |
2738 | 2886 | dc->pc += insn_len; |
2739 | 2887 | if (dc->clear_x) |
... | ... | @@ -2778,7 +2926,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, |
2778 | 2926 | cris_evaluate_flags (dc); |
2779 | 2927 | done: |
2780 | 2928 | if (__builtin_expect(env->singlestep_enabled, 0)) { |
2781 | - gen_op_debug(); | |
2929 | + t_gen_raise_exception(EXCP_DEBUG); | |
2782 | 2930 | } else { |
2783 | 2931 | switch(dc->is_jmp) { |
2784 | 2932 | case DISAS_NEXT: |
... | ... | @@ -2933,13 +3081,16 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) |
2933 | 3081 | pregnames[i]); |
2934 | 3082 | } |
2935 | 3083 | |
2936 | - TCG_HELPER(helper_tlb_update); | |
2937 | - TCG_HELPER(helper_tlb_flush); | |
2938 | - TCG_HELPER(helper_rfe); | |
3084 | + TCG_HELPER(helper_raise_exception); | |
2939 | 3085 | TCG_HELPER(helper_store); |
2940 | 3086 | TCG_HELPER(helper_dump); |
2941 | 3087 | TCG_HELPER(helper_dummy); |
2942 | 3088 | |
3089 | + TCG_HELPER(helper_tlb_flush); | |
3090 | + TCG_HELPER(helper_movl_sreg_reg); | |
3091 | + TCG_HELPER(helper_movl_reg_sreg); | |
3092 | + TCG_HELPER(helper_rfe); | |
3093 | + | |
2943 | 3094 | TCG_HELPER(helper_evaluate_flags_muls); |
2944 | 3095 | TCG_HELPER(helper_evaluate_flags_mulu); |
2945 | 3096 | TCG_HELPER(helper_evaluate_flags_mcp); | ... | ... |