⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 h8s_stub.c

📁 ecos移植到R8H系列的源码。源码包来自http://www.cetoni.de/develop/develop_ecosh8s_en.html
💻 C
📖 第 1 页 / 共 3 页
字号:

    2, 2, 2, 2, 2, 2, 2, 2,       // 6
    2, 2, -1, -1, 2, 2, 4, 4,

    2, 2, 2, 2, 2, 2, 2, 2,       // 7
    8, 4, 6, 4, 4, 4, 4, 4,

    2, 2, 2, 2, 2, 2, 2, 2,       // 8
    2, 2, 2, 2, 2, 2, 2, 2,

    2, 2, 2, 2, 2, 2, 2, 2,       // 9
    2, 2, 2, 2, 2, 2, 2, 2,

    2, 2, 2, 2, 2, 2, 2, 2,       // a
    2, 2, 2, 2, 2, 2, 2, 2,

    2, 2, 2, 2, 2, 2, 2, 2,       // b
    2, 2, 2, 2, 2, 2, 2, 2,

    2, 2, 2, 2, 2, 2, 2, 2,       // c
    2, 2, 2, 2, 2, 2, 2, 2,

    2, 2, 2, 2, 2, 2, 2, 2,       // d
    2, 2, 2, 2, 2, 2, 2, 2,

    2, 2, 2, 2, 2, 2, 2, 2,       // e
    2, 2, 2, 2, 2, 2, 2, 2,

    2, 2, 2, 2, 2, 2, 2, 2,       // f
    2, 2, 2, 2, 2, 2, 2, 2,
   };


   op = (unsigned char *)addr_in;      // opcode ptr
   op_len = Gdb_Op2Len[*op];           // get length from table

   //
   // These if and switch statements calculate the lenght of the
   // opcode which address we received by the function argument
   // It calculates the length of the opcodes marked with -1
   // in the table above.
   //
   if (-1 == op_len)                       // -1 = length not in table
   {
      if (0x6a == *op)                     // it is a bit instruction
      {
         switch (*(op + 1) & 0xf0)         // code following op
         {
            case 0x40 : // fall through       MOVFPE @aa:16,Rd
            case 0xC0 : op_len = 4; break; // MOVTPE Rs,@aa:16
            case 0x10 : // fall through    
            case 0x20 : // fall through
            case 0x80 : // fall through
            case 0xA0 : op_len = 6; break; 
            case 0x30 : op_len = 8; break; // BAND #xx:3,@aa:32
            default   : op_len = 2; break; // error
         }
      }
      else if (0x6b == *op)
      {
         switch (*(op + 1) & 0xf0)         // examine code after opcode
         {
            case 0x00 : // fall through       MOV.W @aa:16,Rd  
            case 0x30 : // fall through       MOV.W Rs,@aa:16
            case 0x80 : op_len = 4; break;
            case 0x20 : // fall through       MOV.W @aa:32,Rd
            case 0xa0 : op_len = 6; break;
            default   : op_len = 2; break; // errorr
         }
      } 
      else if(0x01 == *op)
      {
         if ((0x6aU == *(op + 2)) || (0x6bU == *(op + 2)))
         {
            if (0x20 & *(op + 3))
            {
               op_len = 8;
            }
            else
            {
               op_len = 6;
            }
         }
         else
         {
            op_len = Gdb_Op2Len[*(op + 2)] + 2;
         }
      } // End of else if(0x01 == *op) 
   } // End of if (-1 == op_len) 

   return op_len;
}
   

//============================================================================
//                        IS INSTRUCTION A BRANCH INSTR. ?
///   
///   Checks if H8S instruction is a branch. 
///   The function gets opcode an decides whether it is a branch instruction
///   or not
///
///   \param  op_in   Operation code
///
///   \retval 1 if it is a branch istruction
///   \retval 0 if it is not a branch instruction.
//============================================================================
int GdbIsBranch (HAL_STUB_H8S_INSTR op_in)
{
   //
   // any 4x or 5x opcode is a branch of some kind, except for
   // mulxu (50 and 51) and divxu (52 and 53)
   //
   if ((0x4000U == (op_in & 0xf000U)) || (0x5000U == (op_in & 0xf000U)))
   {
      switch (op_in & 0xff00)
      {
         case 0x5000U :  // fall through
         case 0x5100U :  // fall through
         case 0x5200U :  // fall through
         case 0x5300U : return 0;

         default      : return 1;
      }
   }

   return 0;
}


//============================================================================
//                     GET DESTINATION ADDRESS OF BRANCH
//
///    Get destination address of branch.
///    Function returns destination of branch from actual PC.
///
///    \param pc_in   Program Counter content
///
///    \return Destination address of branch
//============================================================================
long GdbGetBranchDest (long pc_in)
{
   HAL_STUB_H8S_INSTR op;
   signed int         disp;
   long               dest;
   char               ccr;
   short              r;
   unsigned char      instr_len;


   op   = *(HAL_STUB_H8S_INSTR *)pc_in;                   // get instr. PC points to
   dest = pc_in + GdbH8sInstrLen(pc_in);
   ccr  = get_register(CCR);                              // get CCR value from RegFile

   //
   // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte |
   // ---------------+----------+----------+----------+----------+
   // Reg. indirect  | JMP      | @ERn     |  5  |  9 |0|ern|  0 |
   // Reg. indirect  | JSR      | @ERn     |  5  |  D |0|ern|  0 |
   //
   if (GDB_H8S_OP_JMPER(op) || GDB_H8S_OP_JSRER(op))
   {
      r = (op & 0x00f0) >> 4;                        // get register number from 2nd byte
      switch (r)
      {
         case 0 : dest = get_register(ER0); break;
         case 1 : dest = get_register(ER1); break;
         case 2 : dest = get_register(ER2); break;
         case 3 : dest = get_register(ER3); break;
         case 4 : dest = get_register(ER4); break;
         case 5 : dest = get_register(ER5); break;
         case 6 : dest = get_register(ER6); break;
         case 7 : dest = get_register(SP); break;

         default: dest = 0; break;
      }
   }

   //
   // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte | 3rd byte | 4th byte
   // ---------------+----------+----------+----------+----------+----------+---------
   // Abs. address   | JMP      | @aa:24   |  5  |  A |              abs
   // Reg. indirect  | JSR      | @aa:24   |  5  |  E |              abs
   //
   else if (GDB_H8S_OP_JMP24(op) ||
            GDB_H8S_OP_JSR24(op))
   {
      dest = *(unsigned long*)pc_in & 0xffffff;
   }

   //
   // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte |
   // ---------------+----------+----------+----------+----------+
   // Mem. indirect  | JMP      | @@aa:8   |  5  |  B |    abs   |
   // Mem. indirect  | JSR      | @@aa:8   |  5  |  F |    abs   |
   //
   else if (GDB_H8S_OP_JMP8(op) || GDB_H8S_OP_JSR8(op))
   {
      dest = op & 0x00ff;
   }

   //
   // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte |
   // ---------------+----------+----------+----------+----------+
   // PC relative    | BSR      | d:8      |  5  |  5 |   disp   |
   //
   else if (GDB_H8S_OP_BSR8(op))
   {                                                 // we have to add 2 because the displacement
      dest = pc_in + (signed char)(op & 0x00ff) + 2; // is added after executing BSR (size of BSR = 2)
   }                                                 // 'signed char' because we branch -126 to +128 bytes

   //
   // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte | 3rd byte | 4th byte
   // ---------------+----------+----------+----------+----------+----------+---------
   // PC relative    | BSR      | d:16     |  5  |  C |     0    |         disp
   //
   else if (GDB_H8S_OP_BSR16(op))
   {                                                   // we have to add 2 because the displacement
      dest = pc_in + *(signed short*)(pc_in + 2) + 2;  // is added after executing BSR (size of BSR = 2)
   }                                                   // 'signed shor' because we branch -32766 to 32768 bytes

   //
   // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte |
   // ---------------+----------+----------+----------+----------+
   // Reg. direct    | TRAPA    | #x:2     |  5  |  C | 0|IMM| 0 |
   //
   // ATTENTION: we have to be carefull with debugging TRAP instructions
   // this way. If the TRAP vector points to a address in ROM then it
   // is not possible to store a breakpoint there
   //
   else if (GDB_H8S_OP_TRAPA(op))
   {
      r = (op & 0x00f0) >> 4;                 // store vector number 1-3 into r
      dest = ((unsigned long *)(0x20))[r];    // get vector address 0x20, 0x24, 0x28, 0x2C
   }

   //
   // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte |
   // ---------------+----------+----------+----------+----------+
   //       -        | RTE      |          |  5  |  6 |  7  |  0 |
   //       -        | RTS      |          |  5  |  4 |  7  |  0 |
   else if (GDB_H8S_OP_RTS(op))
   {
      dest = (*(unsigned long*)get_register(SP)) & 0xffffff;// target address is in SP
   }
   //
   // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte |
   // ---------------+----------+----------+----------+----------+
   //       -        | RTE      |          |  5  |  6 |  7  |  0 |
   else if (GDB_H8S_OP_RTE(op))
   { 
#if defined(CYGHWR_HAL_H8S_INT_CTRL_MODE_2)  
      //
      // If we are in ICM2 then the SP points to EXR and we have to add
      // 2 in order to get the PC
      //
      dest = (*(unsigned long*)get_register(SP)+2) & 0xffffff;// target address is in SP   
#else 
      //
      // If we are not in ICM2 then the SP directly point to the
      // PC and we can take the address immediatelly
      //
      dest = (*(unsigned long*)get_register(SP)) & 0xffffff;// target address is in SP   
#endif
   }
   //
   // It is a BCC instruction (conditionally branch instruction). Now we
   // have to check the instruction and the condition flags in CCR Register.
   //
   else if (GDB_H8S_OP_BCC8(op) || GDB_H8S_OP_BCC16(op))
   {
      //
      // This is the same for all BCC instructions so we execute it
      // only once here. We get displacement and brach type
      //
      // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte |
      // ---------------+----------+----------+----------+----------+
      // PC relative    |          |  d:8     |  4  |typ |   disp   |
      //
      if (GDB_H8S_OP_BCC8(op))
      {
         disp = (signed char)(op & 0xff);         // get displacement
         r = (op & 0xf00) >> 8;                   // store branch type in r
         instr_len = 2;                           // it is a 2 byte instruction
      }

      //
      // Addresing Mode | Mnemonic | Operands | 1st byte | 2nd byte | 3rd byte | 4th byte |
      // ---------------+----------+----------+----------+----------+----------+----------+
      // PC relative    |          |  d:16    |  5  |  8 | typ |  0 |         disp        |
      //
      else // (GDB_H8S_OP_BCC16(op))
      {
         disp = *(signed short*)(pc_in + 2);     // get displacement
         r = (op & 0x00f0) >> 4;                 // store branch type in r
         instr_len = 4;                          // it is a 4 byte instruction
      }

      //
      // Now we decide what we do for each branch type. If we calculate the
      // branch address, we always have to add the length of the bcc instruction
      // because the PC value used for calculation is the starting address of
      // the instruction immediately following the bcc instruction.
      //
      switch (r)
      {
         //
         // Mnemonic | Meaning                      | Condition                   |
         // ---------+------------------------------+-----------------------------+
         // BRA      | Always                       | true                        |
         //
         case GDB_H8S_OP_BCC_BT :
              dest = pc_in + disp + instr_len;
              break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -