📄 h8s_stub.c
字号:
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 + -