From: Stuart B. <zu...@us...> - 2007-03-19 01:37:45
|
Update of /cvsroot/hppaqemu/hppaqemu/target-hppa In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv15948 Modified Files: translate.c Log Message: Implement field_lowsignext (lsb of the field is used for the sign), and use this for most ops. Branches use field_signext for their displacements. Fix numerous gen_op_movls that were the wrong way round. Improve comments for indexed loads and short displacement loads/stores. Add condition tests for COMICLR, SUBI/SUBIO and ADDI/ADDIO/ADDIT/ADDITO. Index: translate.c =================================================================== RCS file: /cvsroot/hppaqemu/hppaqemu/target-hppa/translate.c,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- translate.c 17 Mar 2007 00:30:51 -0000 1.29 +++ translate.c 17 Mar 2007 00:49:09 -0000 1.30 @@ -79,6 +79,17 @@ return val; } +static uint32_t field_lowsignext(uint32_t val, int start, int length) { + if (val & (1 << start)) { + val >>= start + 1; + val |= ~0 << length; + } else { + val >>= start + 1; + val &= ~(~0 << length); + } + return val; +} + static uint32_t signext(uint32_t val, int length) { if (val & (1 << (length - 1))) val |= ~0 << length; @@ -969,7 +980,7 @@ } else { - uint32_t im5 = field_signext(insn, 16, 5); + uint32_t im5 = field_lowsignext(insn, 16, 5); gen_movl_T0_im(im5); } @@ -1006,7 +1017,7 @@ static void gen_store(uint32_t insn, GenOpFunc *op) { - uint32_t im5 = field_signext(insn, 0, 5); + uint32_t im5 = field_lowsignext(insn, 0, 5); uint32_t r = field(insn, 16, 5); uint32_t b = field(insn, 21, 5); int cmplt = get_ldst_cmplt(insn); @@ -1488,9 +1499,10 @@ case 0x27: /* UADDCMT */ /* FIXME: 'c' specifies unit size */ gen_op_uaddcm_T1_T0(); - if (c || f) + if (c || f) { gen_cond_unit[c](); - /* gen_cond_trap(); */ + /* gen_cond_trap(); */ + } break; case 0x28: /* ADDL */ if (c || f) @@ -1545,36 +1557,36 @@ { uint32_t ext4 = field(insn, 6, 4); switch(ext4) { - case 0x00: /* LDB */ + case 0x00: /* LDBX, LDBS */ gen_load(insn, 0, gen_op_ldb_raw); break; - case 0x01: /* LDH */ + case 0x01: /* LDHX, LDHS */ gen_load(insn, 1, gen_op_ldh_raw); break; - case 0x02: /* LDW */ + case 0x02: /* LDWX, LDWS */ gen_load(insn, 2, gen_op_ldw_raw); break; - case 0x06: /* LDWA */ + case 0x06: /* LDWAX, LDWAS */ gen_op_check_priv0(); gen_load(insn, 2, gen_op_ldw_phys); break; - case 0x07: /* LDCW */ + case 0x07: /* LDCWX, LDCWS */ gen_load(insn, 2, gen_op_ldcw_raw); break; - case 0x08: /* STB */ + case 0x08: /* STBS */ gen_store(insn, gen_op_stb_raw); break; - case 0x09: /* STH */ + case 0x09: /* STHS */ gen_store(insn, gen_op_sth_raw); break; - case 0x0A: /* STW */ + case 0x0A: /* STWS */ gen_store(insn, gen_op_stw_raw); break; - case 0x0C: /* STBY */ + case 0x0C: /* STBYS */ break; - case 0x0E: /* STWA */ + case 0x0E: /* STWAS */ gen_store(insn, gen_op_stw_phys); break; @@ -1655,11 +1667,11 @@ uint32_t b, t, im14; b = field(insn, 21, 5); t = field(insn, 16, 5); - im14 = field_signext(insn, 0, 14); - gen_movl_reg_T0(b); + im14 = field_lowsignext(insn, 0, 14); + gen_movl_T0_reg(b); gen_movl_T1_im(im14); gen_op_addl_T0_T1(); - gen_movl_T0_reg(t); + gen_movl_reg_T0(t); break; } @@ -1675,8 +1687,8 @@ b = field(insn, 21, 5); t = field(insn, 16, 5); s = field(insn, 14, 2); - im14 = field_signext(insn, 0, 14); - gen_movl_reg_T0(b); + im14 = field_lowsignext(insn, 0, 14); + gen_movl_T0_reg(b); gen_movl_T1_im(s); /* gen_op_space_sel_T0_T1(); */ gen_movl_T1_im(im14); @@ -1692,7 +1704,7 @@ gen_op_ldst(ldw); break; } - gen_movl_T1_reg(t); + gen_movl_reg_T1(t); break; } @@ -1703,17 +1715,17 @@ case 0x19: /* STH */ case 0x1a: /* STW */ { - uint32_t b, t, s, im14; + uint32_t b, r, s, im14; b = field(insn, 21, 5); - t = field(insn, 16, 5); + r = field(insn, 16, 5); s = field(insn, 14, 2); - im14 = field_signext(insn, 0, 14); - gen_movl_reg_T0(b); + im14 = field_lowsignext(insn, 0, 14); + gen_movl_T0_reg(b); /* gen_movl_T1_im(s); */ /* gen_op_space_sel_T0_T1(); */ gen_movl_T1_im(im14); gen_op_addl_T0_T1(); - gen_movl_reg_T1(t); + gen_movl_reg_T1(r); switch(op) { case 0x18: /* STB */ gen_op_ldst(stb); @@ -1753,7 +1765,7 @@ { uint32_t r, im5; r = field(insn, 21, 5); - im5 = field_signext(insn, 16, 5); + im5 = field_lowsignext(insn, 16, 5); gen_movl_T0_im(im5); gen_movl_T1_reg(r); break; @@ -1783,24 +1795,38 @@ t = field(insn, 16, 5); c = field(insn, 13, 3); f = field(insn, 12, 1); - im11 = field_signext(insn, 0, 11); - gen_movl_reg_T0(r); + im11 = field_lowsignext(insn, 0, 11); + gen_movl_T0_reg(r); gen_movl_T1_im(im11); - gen_op_add_T1_T0(); + if (c || f) + gen_cond_sub[c](); gen_movl_T0_im(0); - gen_movl_T0_reg(t); - break; + gen_movl_reg_T0(t); + if (c || f) + gen_nullify_cond(dc, (long)dc->tb, f); } + break; } case 0x25: /* SUBI, SUBIO */ { - uint32_t r, t, im11; + uint32_t r, t, c, f, o, im11; r = field(insn, 21, 5); t = field(insn, 16, 5); - im11 = field_signext(insn, 0, 11); - gen_movl_reg_T0(r); + c = field(insn, 13, 3); + f = field(insn, 12, 1); + o = field(insn, 11, 1); + im11 = field_lowsignext(insn, 0, 11); + gen_movl_T0_reg(r); + if (o) { + gen_op_eval_sub_sv(); + /* gen_op_overflow_trap(); */ + } + if (c || f) + gen_cond_sub[c](); gen_op_sub_T1_T0_cc(); + if (c || f) + gen_nullify_cond(dc, (long)dc->tb, f); break; } @@ -1830,7 +1856,7 @@ { uint32_t r, im5; r = field(insn, 21, 5); - im5 = field_signext(insn, 16, 5); + im5 = field_lowsignext(insn, 16, 5); gen_movl_T0_im(im5); gen_movl_T1_reg(r); break; @@ -1853,17 +1879,28 @@ case 0x2c: /* ADDIT, ADDITO */ case 0x2d: /* ADDI, ADDIO */ { - uint32_t r, t, im11; + uint32_t r, t, c, f, o, im11; r = field(insn, 21, 5); t = field(insn, 16, 5); - im11 = field_signext(insn, 0, 11); - gen_movl_reg_T0(r); - gen_movl_T0_im(im11); - if(!field(insn, 11, 1)) - gen_op_addit_T0(); - else - gen_op_addito_T0(); - gen_movl_T0_reg(t); + c = field(insn, 13, 3); + f = field(insn, 12, 1); + o = field(insn, 11, 1); + im11 = field_lowsignext(insn, 0, 11); + gen_movl_T0_reg(r); + gen_movl_T1_im(im11); + if (o) { + gen_op_eval_add_sv(); + /* gen_op_overflow_trap(); */ + } + if (c || f) { + gen_cond_add[c](); + if (op == 0x2c) /* ADDIT, ADDITO: */ + ; /* gen_cond_trap(); */ + } + gen_op_add_T1_T0_cc(); + if ((c || f) && (op == 0x2d)) /* ADDI, ADDIO: */ + gen_nullify_cond(dc, (long)dc->tb, f); + gen_movl_reg_T0(t); break; } |