* NEWS: Add entry for stdio gdbserver.
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index 2e2383664f47a58f4770a2d852d93beac854568a..0b950f27b152e4b2ae72e2f3b52d5713c76f0093 100644 (file)
@@ -1144,7 +1144,7 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
            get_frame_register_signed (frame,
                                       mips_regnum (get_frame_arch (frame))->
                                                fp_control_status);
-         int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01);
+         int cond = ((fcrcs >> 24) & 0xfe) | ((fcrcs >> 23) & 0x01);
 
          if (((cond >> cnum) & 0x01) == tf)
            pc += mips32_relative_offset (inst) + 4;
@@ -1319,9 +1319,9 @@ extended_offset (unsigned int extension)
 {
   CORE_ADDR value;
 
-  value = (extension >> 21) & 0x3f;    /* Extract 15:11.  */
+  value = (extension >> 16) & 0x1f;    /* Extract 15:11.  */
   value = value << 6;
-  value |= (extension >> 16) & 0x1f;   /* Extract 10:5.  */
+  value |= (extension >> 21) & 0x3f;   /* Extract 10:5.  */
   value = value << 5;
   value |= extension & 0x1f;           /* Extract 4:0.  */
 
@@ -1361,14 +1361,13 @@ unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc,
        CORE_ADDR value;
        if (extension)
          {
-           value = extended_offset (extension);
-           value = value << 11;        /* rom for the original value */
-           value |= inst & 0x7ff;      /* eleven bits from instruction */
+           value = extended_offset ((extension << 16) | inst);
+           value = (value ^ 0x8000) - 0x8000;          /* Sign-extend.  */
          }
        else
          {
            value = inst & 0x7ff;
-           /* FIXME : Consider sign extension.  */
+           value = (value ^ 0x400) - 0x400;            /* Sign-extend.  */
          }
        offset = value;
        regx = -1;
@@ -1383,28 +1382,16 @@ unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc,
        CORE_ADDR value;
        if (extension)
          {
-           value = extended_offset (extension);
-           value = value << 8;         /* from the original instruction */
-           value |= inst & 0xff;       /* eleven bits from instruction */
-           regx = (extension >> 8) & 0x07;     /* or i8 funct */
-           if (value & 0x4000)         /* Test the sign bit, bit 26.  */
-             {
-               value &= ~0x3fff;       /* Remove the sign bit.  */
-               value = -value;
-             }
+           value = extended_offset ((extension << 16) | inst);
+           value = (value ^ 0x8000) - 0x8000;          /* Sign-extend.  */
          }
        else
          {
-           value = inst & 0xff;        /* 8 bits */
-           regx = (inst >> 8) & 0x07;  /* or i8 funct */
-           /* FIXME: Do sign extension, this format needs it.  */
-           if (value & 0x80)   /* THIS CONFUSES ME.  */
-             {
-               value &= 0xef;  /* Remove the sign bit.  */
-               value = -value;
-             }
+           value = inst & 0xff;                        /* 8 bits */
+           value = (value ^ 0x80) - 0x80;              /* Sign-extend.  */
          }
        offset = value;
+       regx = (inst >> 8) & 0x07;                      /* i8 funct */
        regy = -1;
        break;
       }
@@ -1450,13 +1437,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
        CORE_ADDR offset;
        struct upk_mips16 upk;
        unpack_mips16 (gdbarch, pc, extension, insn, itype, &upk);
-       offset = upk.offset;
-       if (offset & 0x800)
-         {
-           offset &= 0xeff;
-           offset = -offset;
-         }
-       pc += (offset << 1) + 2;
+       pc += (upk.offset << 1) + 2;
        break;
       }
     case 3:                    /* JAL , JALX - Watch out, these are 32 bit
@@ -1476,7 +1457,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
        struct upk_mips16 upk;
        int reg;
        unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
-       reg = get_frame_register_signed (frame, upk.regx);
+       reg = get_frame_register_signed (frame, mips16_to_32_reg[upk.regx]);
        if (reg == 0)
          pc += (upk.offset << 1) + 2;
        else
@@ -1488,7 +1469,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
        struct upk_mips16 upk;
        int reg;
        unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
-       reg = get_frame_register_signed (frame, upk.regx);
+       reg = get_frame_register_signed (frame, mips16_to_32_reg[upk.regx]);
        if (reg != 0)
          pc += (upk.offset << 1) + 2;
        else
@@ -1520,21 +1501,10 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
            int reg;
            upk.regx = (insn >> 8) & 0x07;
            upk.regy = (insn >> 5) & 0x07;
-           switch (upk.regy)
-             {
-             case 0:
-               reg = upk.regx;
-               break;
-             case 1:
-               reg = 31;
-               break;          /* Function return instruction.  */
-             case 2:
-               reg = upk.regx;
-               break;
-             default:
-               reg = 31;
-               break;          /* BOGUS Guess */
-             }
+           if ((upk.regy & 1) == 0)
+             reg = mips16_to_32_reg[upk.regx];
+           else
+             reg = 31;         /* Function return instruction.  */
            pc = get_frame_register_signed (frame, reg);
          }
        else
@@ -2246,7 +2216,8 @@ restart:
                    || high_word == 0x3408 /* ori $t0,$zero,n */
                   ))
        {
-          load_immediate_bytes += MIPS_INSN32_SIZE;            /* FIXME!  */
+        if (end_prologue_addr == 0)
+          load_immediate_bytes += MIPS_INSN32_SIZE;            /* FIXME!  */
        }
       else
        {
@@ -2620,7 +2591,7 @@ deal_with_atomic_sequence (struct gdbarch *gdbarch,
            return 0; /* fallback to the standard single-step code.  */
          break;
        case 1: /* REGIMM */
-         is_branch = ((itype_rt (insn) & 0xc0) == 0); /* B{LT,GE}Z* */
+         is_branch = ((itype_rt (insn) & 0xc) == 0); /* B{LT,GE}Z* */
          break;
        case 2: /* J */
        case 3: /* JAL */
@@ -5385,7 +5356,6 @@ mips_skip_mips16_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
                 address from those two instructions.  */
 
              CORE_ADDR target_pc = get_frame_register_signed (frame, 2);
-             ULONGEST inst;
              int i;
 
              /* See if the name of the target function is  __fn_stub_*.  */
@@ -5402,11 +5372,15 @@ mips_skip_mips16_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
                 instructions.  FIXME.  */
              for (i = 0, pc = 0; i < 20; i++, target_pc += MIPS_INSN32_SIZE)
                {
-                 inst = mips_fetch_instruction (gdbarch, target_pc);
+                 ULONGEST inst = mips_fetch_instruction (gdbarch, target_pc);
+                 CORE_ADDR addr = inst;
+
                  if ((inst & 0xffff0000) == 0x3c010000)        /* lui $at */
-                   pc = (inst << 16) & 0xffff0000;             /* high word */
+                   pc = (((addr & 0xffff) ^ 0x8000) - 0x8000) << 16;
+                                                               /* high word */
                  else if ((inst & 0xffff0000) == 0x24210000)   /* addiu $at */
-                   return pc | (inst & 0xffff);                /* low word */
+                   return pc + ((addr & 0xffff) ^ 0x8000) - 0x8000;
+                                                               /* low word */
                }
 
              /* Couldn't find the lui/addui pair, so return stub address.  */
This page took 0.028114 seconds and 4 git commands to generate.