aboutsummaryrefslogtreecommitdiff
path: root/decoder/source/i_dec
diff options
context:
space:
mode:
Diffstat (limited to 'decoder/source/i_dec')
-rw-r--r--decoder/source/i_dec/trc_i_decode.cpp17
-rw-r--r--decoder/source/i_dec/trc_idec_arminst.cpp30
2 files changed, 33 insertions, 14 deletions
diff --git a/decoder/source/i_dec/trc_i_decode.cpp b/decoder/source/i_dec/trc_i_decode.cpp
index 614fc1d8b45c..0e0589512002 100644
--- a/decoder/source/i_dec/trc_i_decode.cpp
+++ b/decoder/source/i_dec/trc_i_decode.cpp
@@ -42,7 +42,7 @@ ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info)
struct decode_info info;
info.instr_sub_type = OCSD_S_INSTR_NONE;
- info.arch_version = (uint16_t)(instr_info->pe_type.arch);
+ info.arch_version = instr_info->pe_type.arch;
switch(instr_info->isa)
{
@@ -136,14 +136,12 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info, struct decode_info
if(inst_A64_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link, info))
{
instr_info->type = OCSD_INSTR_BR_INDIRECT;
-// instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode);
}
else if(inst_A64_is_direct_branch_link(instr_info->opcode, &instr_info->is_link, info))
{
inst_A64_branch_destination(instr_info->instr_addr,instr_info->opcode,&branchAddr);
instr_info->type = OCSD_INSTR_BR;
instr_info->branch_addr = (ocsd_vaddr_t)branchAddr;
-// instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode);
}
else if((barrier = inst_A64_barrier(instr_info->opcode)) != ARM_BARRIER_NONE)
{
@@ -160,12 +158,15 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info, struct decode_info
break;
}
}
- else if (instr_info->wfi_wfe_branch)
+ else if (instr_info->wfi_wfe_branch &&
+ inst_A64_wfiwfe(instr_info->opcode, info))
{
- if (inst_A64_wfiwfe(instr_info->opcode))
- {
- instr_info->type = OCSD_INSTR_WFI_WFE;
- }
+ instr_info->type = OCSD_INSTR_WFI_WFE;
+ }
+ else if (OCSD_IS_ARCH_MINVER(info->arch_version, ARCH_AA64))
+ {
+ if (inst_A64_Tstart(instr_info->opcode))
+ instr_info->type = OCSD_INSTR_TSTART;
}
instr_info->is_conditional = inst_A64_is_conditional(instr_info->opcode);
diff --git a/decoder/source/i_dec/trc_idec_arminst.cpp b/decoder/source/i_dec/trc_idec_arminst.cpp
index 3652e84921f3..76951fd38183 100644
--- a/decoder/source/i_dec/trc_idec_arminst.cpp
+++ b/decoder/source/i_dec/trc_idec_arminst.cpp
@@ -244,8 +244,9 @@ int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link, struct decod
int is_direct_branch = 1;
if ((inst & 0x7c000000) == 0x34000000) {
/* CB, TB */
- } else if ((inst & 0xff000010) == 0x54000000) {
+ } else if ((inst & 0xff000000) == 0x54000000) {
/* B<cond> */
+ /* BC<cond> 8.8 / 9.3 arch - bit 4 = 1'b1 */
} else if ((inst & 0x7c000000) == 0x14000000) {
/* B, BL imm */
if (inst & 0x80000000) {
@@ -258,11 +259,26 @@ int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link, struct decod
return is_direct_branch;
}
-int inst_A64_wfiwfe(uint32_t inst)
+int inst_A64_wfiwfe(uint32_t inst, struct decode_info *info)
{
/* WFI, WFE may be traced as branches in etm 4.3++ */
if ((inst & 0xffffffdf) == 0xd503205f)
return 1;
+
+ /* new feature introduced post v8.3 */
+ if (OCSD_IS_ARCH_MINVER(info->arch_version, ARCH_AA64))
+ {
+ /* WFIT / WFET for later archs */
+ if ((inst & 0xffffffc0) == 0xd5031000)
+ return 1;
+ }
+ return 0;
+}
+
+int inst_A64_Tstart(uint32_t inst)
+{
+ if ((inst & 0xffffffe0) == 0xd5233060)
+ return 1;
return 0;
}
@@ -288,7 +304,7 @@ int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct dec
} else if ((inst & 0xffffffff) == 0xd69f03e0) {
/* ERET */
info->instr_sub_type = OCSD_S_INSTR_V8_ERET;
- } else if (info->arch_version >= 0x0803) {
+ } else if (OCSD_IS_ARCH_MINVER(info->arch_version, ARCH_V8r3)) {
/* new pointer auth instr for v8.3 arch */
if ((inst & 0xffdff800) == 0xd71f0800) {
/* BRAA, BRAB, BLRAA, BLRBB */
@@ -399,8 +415,9 @@ int inst_A64_branch_destination(uint64_t addr, uint32_t inst, uint64_t *pnpc)
{
uint64_t npc;
int is_direct_branch = 1;
- if ((inst & 0xff000010) == 0x54000000) {
+ if ((inst & 0xff000000) == 0x54000000) {
/* B<cond> */
+ /* BC<cond> */
npc = addr + ((int32_t)((inst & 0x00ffffe0) << 8) >> 11);
} else if ((inst & 0x7c000000) == 0x14000000) {
/* B, BL imm */
@@ -484,7 +501,7 @@ int inst_A64_is_branch_and_link(uint32_t inst, struct decode_info *info)
} else if ((inst & 0xfc000000) == 0x94000000) {
/* BL */
info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
- } else if (info->arch_version >= 0x0803) {
+ } else if (OCSD_IS_ARCH_MINVER(info->arch_version, ARCH_V8r3)) {
/* new pointer auth instr for v8.3 arch */
if ((inst & 0xfffff800) == 0xd73f0800) {
/* BLRAA, BLRBB */
@@ -553,8 +570,9 @@ int inst_A64_is_conditional(uint32_t inst)
if ((inst & 0x7c000000) == 0x34000000) {
/* CB, TB */
return 1;
- } else if ((inst & 0xff000010) == 0x54000000) {
+ } else if ((inst & 0xff000000) == 0x54000000) {
/* B.cond */
+ /* BC.cond */
return 1;
}
return 0;