tcg-sparc improvements
cover tcg-sparc improvements
As noticed elsewhere on the list mulu2_i32 is missing. Which led me to notice that add2_i32 and sub2_i32 were also missing and also led me to notice that division was incorrectly implemented.
My initial implementation of 32-bit division copied the existing practice of using the 64-bit division insns for sparcv9, with proper sign/zero extensions on the input operands. But that required extra temporaries and quickly got ugly. In the end I thought it was clearer to simply use the 32-bit division insns unconditionally.
That excercise, however, made me notice that 32-bit extension was not special-cased, leading to the final patch.
r~
Richard Henderson (5):
tcg-sparc: Add tcg_out_arithc.
tcg-sparc: Implement add2, sub2, mulu2.
tcg-sparc: Do not remove %o[012] from 'r' constraint.
tcg-sparc: Implement division properly.
tcg-sparc: Implement ext32[su]_i64
tcg/sparc/tcg-target.c | 206 ++++++++++++++++++++++++++++++++---------------- tcg/sparc/tcg-target.h | 8 ++ 2 files changed, 145 insertions(+), 69 deletions(-)
PATCH 1/5 tcg-sparc: Add tcg_out_arithc.
Add a function to handle the register-vs-immediate test for arithmetic.
Also, adjust the OP_32_64 macro so that it auto-indents properly. Rename the gen_arith32 label to gen_arith, since it handles 64-bit arithmetic as well.
--- tcg/sparc/tcg-target.c | 86 ++++++++++++++++++++++++------------------------ 1 files changed, 43 insertions(+), 43 deletions(-)
tcg/sparc/tcg-target.c +43 -43
@@ -285,6 +285,13 @@ static inline void tcg_out_arithi(TCGContext *s, int rd, int rs1, INSN_IMM13(offset)); } +static void tcg_out_arithc (TCGContext *s,int rd,int rs1, +int val2,int val2const,int op) +{ +tcg_out32 (s, op |INSN_RD (rd) |INSN_RS1 (rs1) + | (val2const ?INSN_IMM13 (val2) :INSN_RS2 (val2))); +} +static inline void tcg_out_mov (TCGContext *s,int ret,int arg) {tcg_out_arith (s, ret, arg,TCG_REG_G0 ,ARITH_OR );
@@ -481,10 +488,7 @@ static const uint8_t tcg_cond_to_bcond[10] = {static void tcg_out_cmp (TCGContext *s,TCGArg c1,TCGArg c2,int c2const) { -if (c2const) -tcg_out_arithi (s,TCG_REG_G0 , c1, c2,ARITH_SUBCC ); -else -tcg_out_arith (s,TCG_REG_G0 , c1, c2,ARITH_SUBCC ); +tcg_out_arithc (s,TCG_REG_G0 , c1, c2, c2const,ARITH_SUBCC ); } static void tcg_out_brcond_i32(TCGContext *s, int cond,
@@ -1036,22 +1040,22 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,#if TCG_TARGET_REG_BITS ==64 #define OP_32_64 (x) \ - glue(glue(case INDEX_op_, x), _i32:) \ - glue(glue(case INDEX_op_, x), _i64:) + glue(glue(case INDEX_op_, x), _i32): \ + glue(glue(case INDEX_op_, x), _i64)#else #define OP_32_64 (x) \ - glue(glue(case INDEX_op_, x), _i32:) + glue(glue(case INDEX_op_, x), _i32)#endif -OP_32_64 (ld8u); + OP_32_64(ld8u):tcg_out_ldst (s ,args [0 ],args [1 ],args [2 ],LDUB );break ; -OP_32_64 (ld8s); + OP_32_64(ld8s):tcg_out_ldst (s ,args [0 ],args [1 ],args [2 ],LDSB );break ; -OP_32_64 (ld16u); + OP_32_64(ld16u):tcg_out_ldst (s ,args [0 ],args [1 ],args [2 ],LDUH );break ; -OP_32_64 (ld16s); + OP_32_64(ld16s):tcg_out_ldst (s ,args [0 ],args [1 ],args [2 ],LDSH );break ;case INDEX_op_ld_i32:
@@ -1060,10 +1064,10 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,#endif tcg_out_ldst (s, args[0 ], args[1 ], args[2 ],LDUW );break ; -OP_32_64 (st8); + OP_32_64(st8):tcg_out_ldst (s ,args [0 ],args [1 ],args [2 ],STB );break ; -OP_32_64 (st16); + OP_32_64(st16):tcg_out_ldst (s ,args [0 ],args [1 ],args [2 ],STH );break ;case INDEX_op_st_i32:
@@ -1072,50 +1076,50 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,#endif tcg_out_ldst (s, args[0 ], args[1 ], args[2 ],STW );break ; -OP_32_64 (add); + OP_32_64(add): c =ARITH_ADD ; - goto gen_arith32; -OP_32_64 (sub); + goto gen_arith; + OP_32_64(sub): c =ARITH_SUB ; - goto gen_arith32; -OP_32_64 (and); + goto gen_arith; + OP_32_64(and): c =ARITH_AND ; - goto gen_arith32; -OP_32_64 (or); + goto gen_arith; + OP_32_64(or): c =ARITH_OR ; - goto gen_arith32; -OP_32_64 (xor); + goto gen_arith; + OP_32_64(xor): c =ARITH_XOR ; - goto gen_arith32; + goto gen_arith;case INDEX_op_shl_i32: c =SHIFT_SLL ; - goto gen_arith32; + goto gen_arith;case INDEX_op_shr_i32: c =SHIFT_SRL ; - goto gen_arith32; + goto gen_arith;case INDEX_op_sar_i32: c =SHIFT_SRA ; - goto gen_arith32; + goto gen_arith;case INDEX_op_mul_i32: c =ARITH_UMUL ; - goto gen_arith32; + goto gen_arith;case INDEX_op_div2_i32:#if defined(__sparc_v9__) || defined(__sparc_v8plus__) c =ARITH_SDIVX ; - goto gen_arith32; + goto gen_arith;#else tcg_out_sety (s,0 ); c =ARITH_SDIV ; - goto gen_arith32; + goto gen_arith;#endif case INDEX_op_divu2_i32:#if defined(__sparc_v9__) || defined(__sparc_v8plus__) c =ARITH_UDIVX ; - goto gen_arith32; + goto gen_arith;#else tcg_out_sety (s,0 ); c =ARITH_UDIV ; - goto gen_arith32; + goto gen_arith;#endif case INDEX_op_brcond_i32:
@@ -1173,22 +1177,22 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,break ;case INDEX_op_shl_i64: c =SHIFT_SLLX ; - goto gen_arith32; + goto gen_arith;case INDEX_op_shr_i64: c =SHIFT_SRLX ; - goto gen_arith32; + goto gen_arith;case INDEX_op_sar_i64: c =SHIFT_SRAX ; - goto gen_arith32; + goto gen_arith;case INDEX_op_mul_i64: c =ARITH_MULX ; - goto gen_arith32; + goto gen_arith;case INDEX_op_div2_i64: c =ARITH_SDIVX ; - goto gen_arith32; + goto gen_arith;case INDEX_op_divu2_i64: c =ARITH_UDIVX ; - goto gen_arith32; + goto gen_arith;case INDEX_op_brcond_i64: tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
@@ -1202,12 +1206,8 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,break ;#endif - gen_arith32: -if (const_args[2 ]) { -tcg_out_arithi (s, args[0 ], args[1 ], args[2 ], c); - }else { -tcg_out_arith (s, args[0 ], args[1 ], args[2 ], c); - } + gen_arith: +tcg_out_arithc (s, args[0 ], args[1 ], args[2 ], const_args[2 ], c);break ;default :
Signature · 1 line
1.6.5.2
PATCH 2/5 tcg-sparc: Implement add2, sub2, mulu2.
In reply to Richard HendersonAdd missing 32-bit double-word support opcodes.
--- tcg/sparc/tcg-target.c | 27 +++++++++++++++++++++++++++ 1 files changed, 27 insertions(+), 0 deletions(-)
tcg/sparc/tcg-target.c +27 -0
@@ -215,6 +215,7 @@ static inline int tcg_target_const_match(tcg_target_long val,#define BA (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2))#define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00)) +#define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))#define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01))#define ARITH_OR (INSN_OP(2) | INSN_OP3(0x02))#define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
@@ -238,6 +239,7 @@ static inline int tcg_target_const_match(tcg_target_long val,#define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))#define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12)) +#define RDY (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))#define WRY (INSN_OP(2) | INSN_OP3(0x30))#define JMPL (INSN_OP(2) | INSN_OP3(0x38))#define SAVE (INSN_OP(2) | INSN_OP3(0x3c))
@@ -410,6 +412,11 @@ static inline void tcg_out_sety(TCGContext *s, tcg_target_long val)fprintf (stderr,"unimplemented sety %ld\n" , (long )val); } +static inline void tcg_out_rdy (TCGContext *s,int rd) +{ +tcg_out32 (s,RDY |INSN_RD (rd)); +} +static inline void tcg_out_addi (TCGContext *s,int reg,tcg_target_long val) {if (val !=0 ) {
@@ -1132,6 +1139,23 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, args[2 ], const_args[2 ], args[3], const_args[3], args[5]);break ; +case INDEX_op_add2_i32: +tcg_out_arithc (s, args[0 ], args[2 ], args[4 ], const_args[4 ], +ARITH_ADDCC ); +tcg_out_arithc (s, args[1 ], args[3 ], args[5 ], const_args[5 ], +ARITH_ADDX ); +break ; +case INDEX_op_sub2_i32: +tcg_out_arithc (s, args[0 ], args[2 ], args[4 ], const_args[4 ], +ARITH_SUBCC ); +tcg_out_arithc (s, args[1 ], args[3 ], args[5 ], const_args[5 ], +ARITH_SUBX ); +break ; +case INDEX_op_mulu2_i32: +tcg_out_arithc (s, args[0 ], args[2 ], args[3 ], const_args[3 ], +ARITH_UMUL ); +tcg_out_rdy (s, args[1 ]); +break ;#endif case INDEX_op_qemu_ld8u:
@@ -1250,6 +1274,9 @@ static const TCGTargetOpDef sparc_op_defs[] = { { INDEX_op_brcond_i32, { "r", "rJ" } },#if TCG_TARGET_REG_BITS ==32 { INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } }, + { INDEX_op_add2_i32, { "r", "r", "r", "r", "rJ", "rJ" } }, + { INDEX_op_sub2_i32, { "r", "r", "r", "r", "rJ", "rJ" } }, + { INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } }, #endif { INDEX_op_qemu_ld8u, { "r", "L" } },
Signature · 1 line
1.6.5.2
PATCH 3/5 tcg-sparc: Do not remove %o[012] from 'r' constraint.
In reply to Richard HendersonOnly 'L' constraint needs that.
--- tcg/sparc/tcg-target.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
tcg/sparc/tcg-target.c +3 -0
@@ -143,6 +143,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) ct_str = *pct_str;switch (ct_str[0 ]) {case 'r' : + ct->ct |=TCG_CT_REG ; +tcg_regset_set32 (ct->u.regs,0 ,0xffffffff ); +break ;case 'L' :/* qemu_ld/st constraint */ ct->ct |=TCG_CT_REG ;tcg_regset_set32 (ct->u.regs,0 ,0xffffffff );
Signature · 1 line
1.6.5.2
PATCH 4/5 tcg-sparc: Implement division properly.
In reply to Richard HendersonThe {div,divu}2 opcodes are intended for systems for which the division instruction produces both quotient and remainder. Sparc is not such a system. Indeed, the remainder must be computed as
quot = a / b
rem = a - (quot * b)
Split out a tcg_out_div32 function that properly initializes Y with the extension of the input to 64-bits. Discard the code that used the 64-bit DIVX on sparc9/sparcv8plus without extending the inputs to 64-bits. Implement remainders in terms of division followed by multiplication.
--- tcg/sparc/tcg-target.c | 82 ++++++++++++++++++++++++++++++----------------- tcg/sparc/tcg-target.h | 3 ++ 2 files changed, 55 insertions(+), 30 deletions(-)
tcg/sparc/tcg-target.c +52 -30
@@ -243,7 +243,7 @@ static inline int tcg_target_const_match(tcg_target_long val,#define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))#define RDY (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0)) -#define WRY (INSN_OP(2) | INSN_OP3(0x30)) +#define WRY (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))#define JMPL (INSN_OP(2) | INSN_OP3(0x38))#define SAVE (INSN_OP(2) | INSN_OP3(0x3c))#define RESTORE (INSN_OP(2) | INSN_OP3(0x3d))
@@ -407,12 +407,9 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,tcg_out_ldst (s, arg, arg1, arg2,STX ); } -static inline void tcg_out_sety (TCGContext *s,tcg_target_long val) +static inline void tcg_out_sety (TCGContext *s,int rs) { -if (val ==0 || val ==-1 ) -tcg_out32 (s,WRY |INSN_IMM13 (val)); -else -fprintf (stderr,"unimplemented sety %ld\n" , (long )val); +tcg_out32 (s,WRY |INSN_RS1 (TCG_REG_G0 ) |INSN_RS2 (rs)); }static inline void tcg_out_rdy (TCGContext *s,int rd)
@@ -444,6 +441,21 @@ static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val) } } +static void tcg_out_div32 (TCGContext *s,int rd,int rs1, +int val2,int val2const,int uns) +{ +/* Load Y with the sign/zero extension of RS1 to 64-bits. */ +if (uns) { +tcg_out_sety (s,TCG_REG_G0 ); + }else { +tcg_out_arith (s,TCG_REG_I5 , rs1,31 ,SHIFT_SRA ); +tcg_out_sety (s,TCG_REG_I5 ); + } + +tcg_out_arithc (s, rd, rs1, val2, val2const, + uns ?ARITH_UDIV :ARITH_SDIV ); +} +static inline void tcg_out_nop (TCGContext *s) {tcg_out_sethi (s,TCG_REG_G0 ,0 );
@@ -1113,24 +1125,22 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,case INDEX_op_mul_i32: c =ARITH_UMUL ; goto gen_arith; -case INDEX_op_div2_i32: -#if defined(__sparc_v9__) || defined(__sparc_v8plus__) - c =ARITH_SDIVX ; - goto gen_arith; -#else -tcg_out_sety (s,0 ); - c =ARITH_SDIV ; - goto gen_arith; -#endif -case INDEX_op_divu2_i32: -#if defined(__sparc_v9__) || defined(__sparc_v8plus__) - c =ARITH_UDIVX ; - goto gen_arith; -#else -tcg_out_sety (s,0 ); - c =ARITH_UDIV ; - goto gen_arith; -#endif + +case INDEX_op_div_i32: +tcg_out_div32 (s, args[0 ], args[1 ], args[2 ], const_args[2 ],0 ); +break ; +case INDEX_op_divu_i32: +tcg_out_div32 (s, args[0 ], args[1 ], args[2 ], const_args[2 ],1 ); +break ; + +case INDEX_op_rem_i32: +case INDEX_op_remu_i32: +tcg_out_div32 (s,TCG_REG_I5 , args[1 ], args[2 ], const_args[2 ], + opc == INDEX_op_remu_i32); +tcg_out_arithc (s,TCG_REG_I5 ,TCG_REG_I5 , args[2 ], const_args[2 ], +ARITH_UMUL ); +tcg_out_arith (s, args[0 ], args[1 ],TCG_REG_I5 ,ARITH_SUB ); +break ;case INDEX_op_brcond_i32: tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
@@ -1214,12 +1224,20 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,case INDEX_op_mul_i64: c =ARITH_MULX ; goto gen_arith; -case INDEX_op_div2_i64: +case INDEX_op_div_i64: c =ARITH_SDIVX ; goto gen_arith; -case INDEX_op_divu2_i64: +case INDEX_op_divu_i64: c =ARITH_UDIVX ; goto gen_arith; +case INDEX_op_rem_i64: +case INDEX_op_remu_i64: +tcg_out_arithc (s,TCG_REG_I5 , args[1 ], args[2 ], const_args[2 ], + opc == INDEX_op_rem_i64 ?ARITH_SDIVX :ARITH_UDIVX ); +tcg_out_arithc (s,TCG_REG_I5 ,TCG_REG_I5 , args[2 ], const_args[2 ], +ARITH_MULX ); +tcg_out_arith (s, args[0 ], args[1 ],TCG_REG_I5 ,ARITH_SUB ); +break ;case INDEX_op_brcond_i64: tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
@@ -1263,8 +1281,10 @@ static const TCGTargetOpDef sparc_op_defs[] = { { INDEX_op_add_i32, { "r", "r", "rJ" } }, { INDEX_op_mul_i32, { "r", "r", "rJ" } }, - { INDEX_op_div2_i32, { "r", "r", "0", "1", "r" } }, - { INDEX_op_divu2_i32, { "r", "r", "0", "1", "r" } }, + { INDEX_op_div_i32, { "r", "r", "rJ" } }, + { INDEX_op_divu_i32, { "r", "r", "rJ" } }, + { INDEX_op_rem_i32, { "r", "r", "rJ" } }, + { INDEX_op_remu_i32, { "r", "r", "rJ" } }, { INDEX_op_sub_i32, { "r", "r", "rJ" } }, { INDEX_op_and_i32, { "r", "r", "rJ" } }, { INDEX_op_or_i32, { "r", "r", "rJ" } },
@@ -1312,8 +1332,10 @@ static const TCGTargetOpDef sparc_op_defs[] = { { INDEX_op_add_i64, { "r", "r", "rJ" } }, { INDEX_op_mul_i64, { "r", "r", "rJ" } }, - { INDEX_op_div2_i64, { "r", "r", "0", "1", "r" } }, - { INDEX_op_divu2_i64, { "r", "r", "0", "1", "r" } }, + { INDEX_op_div_i64, { "r", "r", "rJ" } }, + { INDEX_op_divu_i64, { "r", "r", "rJ" } }, + { INDEX_op_rem_i64, { "r", "r", "rJ" } }, + { INDEX_op_remu_i64, { "r", "r", "rJ" } }, { INDEX_op_sub_i64, { "r", "r", "rJ" } }, { INDEX_op_and_i64, { "r", "r", "rJ" } }, { INDEX_op_or_i64, { "r", "r", "rJ" } },
tcg/sparc/tcg-target.h +3 -0
@@ -88,6 +88,9 @@ enum {#endif /* optional instructions */ +#define TCG_TARGET_HAS_div_i32 +#define TCG_TARGET_HAS_div_i64 +//#define TCG_TARGET_HAS_bswap32_i32 //#define TCG_TARGET_HAS_bswap64_i64 //#define TCG_TARGET_HAS_neg_i32
Signature · 1 line
1.6.5.2
Re: [Qemu-devel] [PATCH 4/5] tcg-sparc: Implement division properly.
tcg/sparc/tcg-target.c static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val) · line 451
Quoted 5 lines · Richard Henderson
tcg/sparc/tcg-target.c +5
-0+/* Load Y with the sign/zero extension of RS1 to 64-bits. */ +if (uns) { +tcg_out_sety (s,TCG_REG_G0 ); + }else { +tcg_out_arith (s,TCG_REG_I5 , rs1,31 ,SHIFT_SRA );
Bah. tcg_out_arithi.
Programming by code inspection only sucks.
r~
PATCH 5/5 tcg-sparc: Implement ext32[su]_i64
In reply to Richard HendersonThe 32-bit right-shift instructions is defined to extend the shifted output to 64-bits. A shift count of zero therefore is a simple extension without actually shifting.
--- tcg/sparc/tcg-target.c | 16 ++++++++++++++++ tcg/sparc/tcg-target.h | 5 +++++ 2 files changed, 21 insertions(+), 0 deletions(-)
tcg/sparc/tcg-target.c +16 -0
@@ -1238,6 +1238,20 @@ static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, ARITH_MULX);tcg_out_arith (s, args[0 ], args[1 ],TCG_REG_I5 ,ARITH_SUB );break ; +case INDEX_op_ext32s_i64: +if (const_args[1 ]) { +tcg_out_movi (s,TCG_TYPE_I64 , args[0 ], (int32_t )args[1 ]); + }else { +tcg_out_arithi (s, args[0 ], args[1 ],0 ,SHIFT_SRA ); + } +break ; +case INDEX_op_ext32u_i64: +if (const_args[1 ]) { +tcg_out_movi_imm32 (s, args[0 ], args[1 ]); + }else { +tcg_out_arithi (s, args[0 ], args[1 ],0 ,SHIFT_SRL ); + } +break ;case INDEX_op_brcond_i64: tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
@@ -1344,6 +1358,8 @@ static const TCGTargetOpDef sparc_op_defs[] = { { INDEX_op_shl_i64, { "r", "r", "rJ" } }, { INDEX_op_shr_i64, { "r", "r", "rJ" } }, { INDEX_op_sar_i64, { "r", "r", "rJ" } }, + { INDEX_op_ext32s_i64, { "r", "ri" } }, + { INDEX_op_ext32u_i64, { "r", "ri" } }, { INDEX_op_brcond_i64, { "r", "rJ" } }, #endif
tcg/sparc/tcg-target.h +5 -0
@@ -91,6 +91,11 @@ enum {#define TCG_TARGET_HAS_div_i32#define TCG_TARGET_HAS_div_i64 +#if TCG_TARGET_REG_BITS ==64 +#define TCG_TARGET_HAS_ext32s_i64 +#define TCG_TARGET_HAS_ext32u_i64 +#endif +//#define TCG_TARGET_HAS_bswap32_i32 //#define TCG_TARGET_HAS_bswap64_i64 //#define TCG_TARGET_HAS_neg_i32
Signature · 1 line
1.6.5.2
Quoted 8 lines · Richard Henderson
Richard Henderson (5):
tcg-sparc: Addtcg_out_arithc.
tcg-sparc: Implement add2, sub2, mulu2.
tcg-sparc: Do not remove %o[012] from 'r' constraint.
tcg-sparc: Implement division properly.
tcg-sparc: Implement ext32[su]_i64
Great work :-) Now the NetBSD malta kernel boots using qemu-system-mips on a sparc target!
log:
uname -a
SunOS opensolaris 5.11 snv_111b sun4u sparc SUNW,Ultra-5_10 Solaris
./mips-softmmu/qemu-system-mips --kernel ../../netbsd_malta -m 64 -nographic
MIPS32/64 params: cpu arch: 32
MIPS32/64 params: TLB entries: 16
MIPS32/64 params: Icache: line = 16, total = 2048, ways = 2
sets = 64
MIPS32/64 params: Dcache: line = 16, total = 2048, ways = 2
sets = 64 picache_stride = 1024
picache_loopcount = 2
pdcache_stride = 1024
pdcache_loopcount = 2
[ Kernel symbol table missing! ]
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
NetBSD 5.0.1 (MALTA) #0: Wed Jul 29 19:36:39 UTC 2009
[email protected]:/home/builds/ab/netbsd-5-0-1-RELEASE/evbmips-mipseb/200907292356Z-obj/home/builds/ab/netbsd-5-0-1-RELEASE/src/sys/arch/evbmips/compile/MALTA total memory = 65536 KB
avail memory = 59460 KB
mainbus0 (root)
cpu0 at mainbus0: 2152.04MHz (hz cycles = 10760233, delay divisor = 1076)
cpu0: MIPS 24K (0x19300) Rev. 0 with software emulated floating point
cpu0: 2KB/16B 2-way set-associative L1 Instruction cache, 16 TLB entries
cpu0: 2KB/16B 2-way set-associative write-back L1 Data cache
gt0 at mainbus0 addr 0x1be00000
pci0 at gt0
Blue Swirl
AppliedQuoted 4 lines · Richard Henderson
As noticed elsewhere on the list
mulu2_i32is missing. Which led me to notice thatadd2_i32andsub2_i32were also missing and also led me to notice that division was incorrectly implemented.
Quoted 8 lines
My initial implementation of 32-bit division copied the existing practice of using the 64-bit division insns for sparcv9, with proper sign/zero extensions on the input operands. But that required extra temporaries and quickly got ugly. In the end I thought it was clearer to simply use the 32-bit division insns unconditionally.
That excercise, however, made me notice that 32-bit extension was not special-cased, leading to the final patch.
Thanks, applied all (4/5 with your fix).