Commit d059c17270bdfa1b4054a98e1c65360af81ece9c

Authored by edgar_igl
1 parent 7dd7c987

CRIS: Convert lz (leading zeros) to TCG.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4309 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 69 additions and 1 deletions
target-cris/translate.c
@@ -307,6 +307,74 @@ static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b) @@ -307,6 +307,74 @@ static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
307 tcg_gen_discard_i64(t1); 307 tcg_gen_discard_i64(t1);
308 } 308 }
309 309
  310 +/* 32bit branch-free binary search for counting leading zeros. */
  311 +static void t_gen_lz_i32(TCGv d, TCGv x)
  312 +{
  313 + TCGv y, m, n;
  314 +
  315 + y = tcg_temp_new(TCG_TYPE_I32);
  316 + m = tcg_temp_new(TCG_TYPE_I32);
  317 + n = tcg_temp_new(TCG_TYPE_I32);
  318 +
  319 + /* y = -(x >> 16) */
  320 + tcg_gen_shri_i32(y, x, 16);
  321 + tcg_gen_sub_i32(y, tcg_const_i32(0), y);
  322 +
  323 + /* m = (y >> 16) & 16 */
  324 + tcg_gen_sari_i32(m, y, 16);
  325 + tcg_gen_andi_i32(m, m, 16);
  326 +
  327 + /* n = 16 - m */
  328 + tcg_gen_sub_i32(n, tcg_const_i32(16), m);
  329 + /* x = x >> m */
  330 + tcg_gen_shr_i32(x, x, m);
  331 +
  332 + /* y = x - 0x100 */
  333 + tcg_gen_subi_i32(y, x, 0x100);
  334 + /* m = (y >> 16) & 8 */
  335 + tcg_gen_sari_i32(m, y, 16);
  336 + tcg_gen_andi_i32(m, m, 8);
  337 + /* n = n + m */
  338 + tcg_gen_add_i32(n, n, m);
  339 + /* x = x << m */
  340 + tcg_gen_shl_i32(x, x, m);
  341 +
  342 + /* y = x - 0x1000 */
  343 + tcg_gen_subi_i32(y, x, 0x1000);
  344 + /* m = (y >> 16) & 4 */
  345 + tcg_gen_sari_i32(m, y, 16);
  346 + tcg_gen_andi_i32(m, m, 4);
  347 + /* n = n + m */
  348 + tcg_gen_add_i32(n, n, m);
  349 + /* x = x << m */
  350 + tcg_gen_shl_i32(x, x, m);
  351 +
  352 + /* y = x - 0x4000 */
  353 + tcg_gen_subi_i32(y, x, 0x4000);
  354 + /* m = (y >> 16) & 2 */
  355 + tcg_gen_sari_i32(m, y, 16);
  356 + tcg_gen_andi_i32(m, m, 2);
  357 + /* n = n + m */
  358 + tcg_gen_add_i32(n, n, m);
  359 + /* x = x << m */
  360 + tcg_gen_shl_i32(x, x, m);
  361 +
  362 + /* y = x >> 14 */
  363 + tcg_gen_shri_i32(y, x, 14);
  364 + /* m = y & ~(y >> 1) */
  365 + tcg_gen_sari_i32(m, y, 1);
  366 + tcg_gen_xori_i32(m, m, 0xffffffff);
  367 + tcg_gen_and_i32(m, m, y);
  368 +
  369 + /* d = n + 2 - m */
  370 + tcg_gen_addi_i32(d, n, 2);
  371 + tcg_gen_sub_i32(d, d, m);
  372 +
  373 + tcg_gen_discard_i32(y);
  374 + tcg_gen_discard_i32(m);
  375 + tcg_gen_discard_i32(n);
  376 +}
  377 +
310 /* Extended arithmetics on CRIS. */ 378 /* Extended arithmetics on CRIS. */
311 static inline void t_gen_add_flag(TCGv d, int flag) 379 static inline void t_gen_add_flag(TCGv d, int flag)
312 { 380 {
@@ -632,7 +700,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size) @@ -632,7 +700,7 @@ static void crisv32_alu_op(DisasContext *dc, int op, int rd, int size)
632 t_gen_subx_carry(cpu_T[0]); 700 t_gen_subx_carry(cpu_T[0]);
633 break; 701 break;
634 case CC_OP_LZ: 702 case CC_OP_LZ:
635 - gen_op_lz_T0_T1(); 703 + t_gen_lz_i32(cpu_T[0], cpu_T[1]);
636 break; 704 break;
637 case CC_OP_BTST: 705 case CC_OP_BTST:
638 gen_op_btst_T0_T1(); 706 gen_op_btst_T0_T1();