Commit 6f06939b6877bdfcac7d466e876022889d2fe59c

Authored by aurel32
1 parent 79383c9c

SH4: convert some more arithmetics ops to TCG

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5116 c046a42c-6fe2-441c-8c8c-71466251a162
target-sh4/exec.h
... ... @@ -71,23 +71,12 @@ int find_itlb_entry(CPUState * env, target_ulong address,
71 71 int use_asid, int update);
72 72 int find_utlb_entry(CPUState * env, target_ulong address, int use_asid);
73 73  
74   -void helper_addc_T0_T1(void);
75   -void helper_addv_T0_T1(void);
76 74 void helper_div1_T0_T1(void);
77   -void helper_dmulsl_T0_T1(void);
78   -void helper_dmulul_T0_T1(void);
79   -void helper_macl_T0_T1(void);
80   -void helper_macw_T0_T1(void);
81   -void helper_negc_T0(void);
82   -void helper_subc_T0_T1(void);
83   -void helper_subv_T0_T1(void);
84 75 void helper_rotcl(uint32_t * addr);
85 76 void helper_rotcr(uint32_t * addr);
86   -void helper_ldtlb(void);
87 77  
88 78 void do_interrupt(CPUState * env);
89 79  
90 80 void cpu_loop_exit(void);
91   -void do_raise_exception(void);
92 81  
93 82 #endif /* _EXEC_SH4_H */
... ...
target-sh4/helper.h
... ... @@ -8,3 +8,11 @@ DEF_HELPER(void, helper_raise_slot_illegal_instruction, (void))
8 8 DEF_HELPER(void, helper_debug, (void))
9 9 DEF_HELPER(void, helper_sleep, (void))
10 10 DEF_HELPER(void, helper_trapa, (uint32_t))
  11 +
  12 +DEF_HELPER(uint32_t, helper_addv, (uint32_t, uint32_t))
  13 +DEF_HELPER(uint32_t, helper_addc, (uint32_t, uint32_t))
  14 +DEF_HELPER(uint32_t, helper_subv, (uint32_t, uint32_t))
  15 +DEF_HELPER(uint32_t, helper_subc, (uint32_t, uint32_t))
  16 +DEF_HELPER(uint32_t, helper_negc, (uint32_t))
  17 +DEF_HELPER(void, helper_macl, (uint32_t, uint32_t))
  18 +DEF_HELPER(void, helper_macw, (uint32_t, uint32_t))
... ...
target-sh4/op.c
... ... @@ -37,30 +37,6 @@ static inline void cond_t(int cond)
37 37 clr_t();
38 38 }
39 39  
40   -void OPPROTO op_frchg(void)
41   -{
42   - env->fpscr ^= FPSCR_FR;
43   - RETURN();
44   -}
45   -
46   -void OPPROTO op_fschg(void)
47   -{
48   - env->fpscr ^= FPSCR_SZ;
49   - RETURN();
50   -}
51   -
52   -void OPPROTO op_addc_T0_T1(void)
53   -{
54   - helper_addc_T0_T1();
55   - RETURN();
56   -}
57   -
58   -void OPPROTO op_addv_T0_T1(void)
59   -{
60   - helper_addv_T0_T1();
61   - RETURN();
62   -}
63   -
64 40 void OPPROTO op_cmp_str_T0_T1(void)
65 41 {
66 42 cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) ||
... ... @@ -90,54 +66,6 @@ void OPPROTO op_div1_T0_T1(void)
90 66 RETURN();
91 67 }
92 68  
93   -void OPPROTO op_dmulsl_T0_T1(void)
94   -{
95   - helper_dmulsl_T0_T1();
96   - RETURN();
97   -}
98   -
99   -void OPPROTO op_dmulul_T0_T1(void)
100   -{
101   - helper_dmulul_T0_T1();
102   - RETURN();
103   -}
104   -
105   -void OPPROTO op_macl_T0_T1(void)
106   -{
107   - helper_macl_T0_T1();
108   - RETURN();
109   -}
110   -
111   -void OPPROTO op_macw_T0_T1(void)
112   -{
113   - helper_macw_T0_T1();
114   - RETURN();
115   -}
116   -
117   -void OPPROTO op_mull_T0_T1(void)
118   -{
119   - env->macl = (T0 * T1) & 0xffffffff;
120   - RETURN();
121   -}
122   -
123   -void OPPROTO op_mulsw_T0_T1(void)
124   -{
125   - env->macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1;
126   - RETURN();
127   -}
128   -
129   -void OPPROTO op_muluw_T0_T1(void)
130   -{
131   - env->macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1;
132   - RETURN();
133   -}
134   -
135   -void OPPROTO op_negc_T0(void)
136   -{
137   - helper_negc_T0();
138   - RETURN();
139   -}
140   -
141 69 void OPPROTO op_shad_T0_T1(void)
142 70 {
143 71 if ((T0 & 0x80000000) == 0)
... ... @@ -160,25 +88,6 @@ void OPPROTO op_shld_T0_T1(void)
160 88 RETURN();
161 89 }
162 90  
163   -void OPPROTO op_subc_T0_T1(void)
164   -{
165   - helper_subc_T0_T1();
166   - RETURN();
167   -}
168   -
169   -void OPPROTO op_subv_T0_T1(void)
170   -{
171   - helper_subv_T0_T1();
172   - RETURN();
173   -}
174   -
175   -void OPPROTO op_ldcl_rMplus_rN_bank(void)
176   -{
177   - env->gregs[PARAM2] = env->gregs[PARAM1];
178   - env->gregs[PARAM1] += 4;
179   - RETURN();
180   -}
181   -
182 91 void OPPROTO op_ldc_T0_sr(void)
183 92 {
184 93 env->sr = T0 & 0x700083f3;
... ... @@ -237,7 +146,7 @@ void OPPROTO op_rotcr_Rn(void)
237 146 RETURN();
238 147 }
239 148  
240   -void OPPROTO op_rotl_Rn(void)
  149 +void OPPROTO op_rotl_Rn(void)
241 150 {
242 151 cond_t(env->gregs[PARAM1] & 0x80000000);
243 152 env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T);
... ...
target-sh4/op_helper.c
... ... @@ -108,36 +108,37 @@ void helper_trapa(uint32_t tra)
108 108 cpu_loop_exit();
109 109 }
110 110  
111   -void helper_addc_T0_T1(void)
  111 +uint32_t helper_addc(uint32_t arg0, uint32_t arg1)
112 112 {
113 113 uint32_t tmp0, tmp1;
114 114  
115   - tmp1 = T0 + T1;
116   - tmp0 = T1;
117   - T1 = tmp1 + (env->sr & 1);
  115 + tmp1 = arg0 + arg1;
  116 + tmp0 = arg1;
  117 + arg1 = tmp1 + (env->sr & 1);
118 118 if (tmp0 > tmp1)
119 119 env->sr |= SR_T;
120 120 else
121 121 env->sr &= ~SR_T;
122   - if (tmp1 > T1)
  122 + if (tmp1 > arg1)
123 123 env->sr |= SR_T;
  124 + return arg1;
124 125 }
125 126  
126   -void helper_addv_T0_T1(void)
  127 +uint32_t helper_addv(uint32_t arg0, uint32_t arg1)
127 128 {
128 129 uint32_t dest, src, ans;
129 130  
130   - if ((int32_t) T1 >= 0)
  131 + if ((int32_t) arg1 >= 0)
131 132 dest = 0;
132 133 else
133 134 dest = 1;
134   - if ((int32_t) T0 >= 0)
  135 + if ((int32_t) arg0 >= 0)
135 136 src = 0;
136 137 else
137 138 src = 1;
138 139 src += dest;
139   - T1 += T0;
140   - if ((int32_t) T1 >= 0)
  140 + arg1 += arg0;
  141 + if ((int32_t) arg1 >= 0)
141 142 ans = 0;
142 143 else
143 144 ans = 1;
... ... @@ -149,6 +150,7 @@ void helper_addv_T0_T1(void)
149 150 env->sr &= ~SR_T;
150 151 } else
151 152 env->sr &= ~SR_T;
  153 + return arg1;
152 154 }
153 155  
154 156 #define T (env->sr & SR_T)
... ... @@ -268,30 +270,12 @@ void helper_div1_T0_T1(void)
268 270 //printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T);
269 271 }
270 272  
271   -void helper_dmulsl_T0_T1()
272   -{
273   - int64_t res;
274   -
275   - res = (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
276   - env->mach = (res >> 32) & 0xffffffff;
277   - env->macl = res & 0xffffffff;
278   -}
279   -
280   -void helper_dmulul_T0_T1()
281   -{
282   - uint64_t res;
283   -
284   - res = (uint64_t) (uint32_t) T0 *(uint64_t) (uint32_t) T1;
285   - env->mach = (res >> 32) & 0xffffffff;
286   - env->macl = res & 0xffffffff;
287   -}
288   -
289   -void helper_macl_T0_T1()
  273 +void helper_macl(uint32_t arg0, uint32_t arg1)
290 274 {
291 275 int64_t res;
292 276  
293 277 res = ((uint64_t) env->mach << 32) | env->macl;
294   - res += (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1;
  278 + res += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1;
295 279 env->mach = (res >> 32) & 0xffffffff;
296 280 env->macl = res & 0xffffffff;
297 281 if (env->sr & SR_S) {
... ... @@ -302,12 +286,12 @@ void helper_macl_T0_T1()
302 286 }
303 287 }
304 288  
305   -void helper_macw_T0_T1()
  289 +void helper_macw(uint32_t arg0, uint32_t arg1)
306 290 {
307 291 int64_t res;
308 292  
309 293 res = ((uint64_t) env->mach << 32) | env->macl;
310   - res += (int64_t) (int16_t) T0 *(int64_t) (int16_t) T1;
  294 + res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1;
311 295 env->mach = (res >> 32) & 0xffffffff;
312 296 env->macl = res & 0xffffffff;
313 297 if (env->sr & SR_S) {
... ... @@ -321,50 +305,52 @@ void helper_macw_T0_T1()
321 305 }
322 306 }
323 307  
324   -void helper_negc_T0()
  308 +uint32_t helper_negc(uint32_t arg)
325 309 {
326 310 uint32_t temp;
327 311  
328   - temp = -T0;
329   - T0 = temp - (env->sr & SR_T);
  312 + temp = -arg;
  313 + arg = temp - (env->sr & SR_T);
330 314 if (0 < temp)
331 315 env->sr |= SR_T;
332 316 else
333 317 env->sr &= ~SR_T;
334   - if (temp < T0)
  318 + if (temp < arg)
335 319 env->sr |= SR_T;
  320 + return arg;
336 321 }
337 322  
338   -void helper_subc_T0_T1()
  323 +uint32_t helper_subc(uint32_t arg0, uint32_t arg1)
339 324 {
340 325 uint32_t tmp0, tmp1;
341 326  
342   - tmp1 = T1 - T0;
343   - tmp0 = T1;
344   - T1 = tmp1 - (env->sr & SR_T);
  327 + tmp1 = arg1 - arg0;
  328 + tmp0 = arg1;
  329 + arg1 = tmp1 - (env->sr & SR_T);
345 330 if (tmp0 < tmp1)
346 331 env->sr |= SR_T;
347 332 else
348 333 env->sr &= ~SR_T;
349   - if (tmp1 < T1)
  334 + if (tmp1 < arg1)
350 335 env->sr |= SR_T;
  336 + return arg1;
351 337 }
352 338  
353   -void helper_subv_T0_T1()
  339 +uint32_t helper_subv(uint32_t arg0, uint32_t arg1)
354 340 {
355 341 int32_t dest, src, ans;
356 342  
357   - if ((int32_t) T1 >= 0)
  343 + if ((int32_t) arg1 >= 0)
358 344 dest = 0;
359 345 else
360 346 dest = 1;
361   - if ((int32_t) T0 >= 0)
  347 + if ((int32_t) arg0 >= 0)
362 348 src = 0;
363 349 else
364 350 src = 1;
365 351 src += dest;
366   - T1 -= T0;
367   - if ((int32_t) T1 >= 0)
  352 + arg1 -= arg0;
  353 + if ((int32_t) arg1 >= 0)
368 354 ans = 0;
369 355 else
370 356 ans = 1;
... ... @@ -376,6 +362,7 @@ void helper_subv_T0_T1()
376 362 env->sr &= ~SR_T;
377 363 } else
378 364 env->sr &= ~SR_T;
  365 + return arg1;
379 366 }
380 367  
381 368 void helper_rotcl(uint32_t * addr)
... ...
target-sh4/translate.c
... ... @@ -417,11 +417,11 @@ void _decode_opc(DisasContext * ctx)
417 417 gen_set_t();
418 418 return;
419 419 case 0xfbfd: /* frchg */
420   - gen_op_frchg();
  420 + tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
421 421 ctx->bstate = BS_STOP;
422 422 return;
423 423 case 0xf3fd: /* fschg */
424   - gen_op_fschg();
  424 + tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
425 425 ctx->bstate = BS_STOP;
426 426 return;
427 427 case 0x0009: /* nop */
... ... @@ -632,16 +632,10 @@ void _decode_opc(DisasContext * ctx)
632 632 tcg_gen_add_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
633 633 return;
634 634 case 0x300e: /* addc Rm,Rn */
635   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
636   - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
637   - gen_op_addc_T0_T1();
638   - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
  635 + tcg_gen_helper_1_2(helper_addc, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
639 636 return;
640 637 case 0x300f: /* addv Rm,Rn */
641   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
642   - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
643   - gen_op_addv_T0_T1();
644   - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
  638 + tcg_gen_helper_1_2(helper_addv, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
645 639 return;
646 640 case 0x2009: /* and Rm,Rn */
647 641 tcg_gen_and_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
... ... @@ -688,14 +682,36 @@ void _decode_opc(DisasContext * ctx)
688 682 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
689 683 return;
690 684 case 0x300d: /* dmuls.l Rm,Rn */
691   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
692   - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
693   - gen_op_dmulsl_T0_T1();
  685 + {
  686 + TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
  687 + TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
  688 +
  689 + tcg_gen_ext_i32_i64(tmp1, cpu_gregs[REG(B7_4)]);
  690 + tcg_gen_ext_i32_i64(tmp2, cpu_gregs[REG(B11_8)]);
  691 + tcg_gen_mul_i64(tmp1, tmp1, tmp2);
  692 + tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
  693 + tcg_gen_shri_i64(tmp1, tmp1, 32);
  694 + tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
  695 +
  696 + tcg_temp_free(tmp1);
  697 + tcg_temp_free(tmp2);
  698 + }
694 699 return;
695 700 case 0x3005: /* dmulu.l Rm,Rn */
696   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
697   - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
698   - gen_op_dmulul_T0_T1();
  701 + {
  702 + TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
  703 + TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
  704 +
  705 + tcg_gen_extu_i32_i64(tmp1, cpu_gregs[REG(B7_4)]);
  706 + tcg_gen_extu_i32_i64(tmp2, cpu_gregs[REG(B11_8)]);
  707 + tcg_gen_mul_i64(tmp1, tmp1, tmp2);
  708 + tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
  709 + tcg_gen_shri_i64(tmp1, tmp1, 32);
  710 + tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
  711 +
  712 + tcg_temp_free(tmp1);
  713 + tcg_temp_free(tmp2);
  714 + }
699 715 return;
700 716 case 0x600e: /* exts.b Rm,Rn */
701 717 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
... ... @@ -725,7 +741,7 @@ void _decode_opc(DisasContext * ctx)
725 741 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
726 742 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
727 743 gen_op_ldl_T0_T0(ctx);
728   - gen_op_macl_T0_T1();
  744 + tcg_gen_helper_0_2(helper_macl, cpu_T[0], cpu_T[1]);
729 745 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 4);
730 746 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
731 747 return;
... ... @@ -735,38 +751,28 @@ void _decode_opc(DisasContext * ctx)
735 751 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
736 752 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
737 753 gen_op_ldl_T0_T0(ctx);
738   - gen_op_macw_T0_T1();
  754 + tcg_gen_helper_0_2(helper_macw, cpu_T[0], cpu_T[1]);
739 755 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
740 756 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 2);
741 757 return;
742 758 case 0x0007: /* mul.l Rm,Rn */
743   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
744   - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
745   - gen_op_mull_T0_T1();
  759 + tcg_gen_mul_i32(cpu_macl, cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
746 760 return;
747 761 case 0x200f: /* muls.w Rm,Rn */
748   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
749   - tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
750   - tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
751   - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
752   - tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
753   - tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]);
754   - gen_op_mulsw_T0_T1();
  762 + tcg_gen_ext16s_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
  763 + tcg_gen_ext16s_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
  764 + tcg_gen_mul_i32(cpu_macl, cpu_T[0], cpu_T[1]);
755 765 return;
756 766 case 0x200e: /* mulu.w Rm,Rn */
757   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
758   - tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
759   - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
760   - tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
761   - gen_op_muluw_T0_T1();
  767 + tcg_gen_ext16u_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
  768 + tcg_gen_ext16u_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
  769 + tcg_gen_mul_i32(cpu_macl, cpu_T[0], cpu_T[1]);
762 770 return;
763 771 case 0x600b: /* neg Rm,Rn */
764 772 tcg_gen_neg_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
765 773 return;
766 774 case 0x600a: /* negc Rm,Rn */
767   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
768   - gen_op_negc_T0();
769   - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
  775 + tcg_gen_helper_1_1(helper_negc, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
770 776 return;
771 777 case 0x6007: /* not Rm,Rn */
772 778 tcg_gen_not_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
... ... @@ -790,16 +796,10 @@ void _decode_opc(DisasContext * ctx)
790 796 tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
791 797 return;
792 798 case 0x300a: /* subc Rm,Rn */
793   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
794   - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
795   - gen_op_subc_T0_T1();
796   - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
  799 + tcg_gen_helper_1_2(helper_subc, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
797 800 return;
798 801 case 0x300b: /* subv Rm,Rn */
799   - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
800   - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
801   - gen_op_subv_T0_T1();
802   - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
  802 + tcg_gen_helper_1_2(helper_subv, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
803 803 return;
804 804 case 0x2008: /* tst Rm,Rn */
805 805 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
... ...