Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions arch/armv7/armv7_disasm/armv7.h
Original file line number Diff line number Diff line change
Expand Up @@ -910,15 +910,23 @@ typedef union _ieee754 {
float fvalue;
}ieee754;

typedef union _ieee754_double {
typedef union _ieee754_double
{
uint64_t value;
struct {
uint64_t fraction:52;
uint64_t exponent:11;
uint64_t sign:1;
struct
{
uint64_t fraction : 52;
uint64_t exponent : 11;
uint64_t sign : 1;
};
double fvalue;
}ieee754_double;
} ieee754_double;

struct DoubleWordRegisterList
{
uint8_t size;
uint8_t start;
};

#ifndef __cplusplus
typedef enum OperandClass OperandClass;
Expand Down
65 changes: 63 additions & 2 deletions arch/armv7/il.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,28 @@ static void ConditionExecute(LowLevelILFunction& il, Condition cond, ExprId true
il.AddInstruction(trueCase);
il.MarkLabel(falseCode);
}

// Returns an instructions datatype size in bits
static size_t GetDataTypeSize(DataType dt)
{
switch (dt)
{
case DT_I8:
case DT_8:
return 8;
case DT_F16:
case DT_I16:
case DT_16:
return 16;
case DT_F32:
case DT_I32:
case DT_32:
return 32;
case DT_F64:
case DT_I64:
case DT_64:
return 64;
}
}

static ExprId GetShifted(LowLevelILFunction& il, Register reg, uint32_t ShiftAmount, Shift shift)
{
Expand Down Expand Up @@ -159,7 +180,22 @@ static ExprId GetShifted(LowLevelILFunction& il, Register reg, uint32_t ShiftAmo
return 0;
}
}

static DoubleWordRegisterList ReadRegisterList(InstructionOperand instr) {
uint32_t val = instr.reg;
DoubleWordRegisterList dwrl;
#ifdef _MSC_VER
dwrl.size = __popcnt(val);
DWORD pos = 0;
_BitScanForward(&pos, val);
dwrl.start = pos;

#else
dwrl.size = __builtin_popcount(val);
dwrl.start = __builtin_ctz(val);

#endif
return dwrl;
}

static ExprId GetShiftedOffset(LowLevelILFunction& il, InstructionOperand& op)
{
Expand Down Expand Up @@ -5086,6 +5122,31 @@ bool GetLowLevelILForArmInstruction(Architecture* arch, uint64_t addr, LowLevelI
)
);
break;
case ARMV7_VLD1:
ConditionExecute(addrSize, instr.cond, instr, il, [&](size_t addrSize, Instruction& instr, LowLevelILFunction& il) {
switch (op1.cls)
{
case OperandClass::REG_LIST_DOUBLE:
DoubleWordRegisterList reglist = ReadRegisterList(op1);
uint32_t dregsize = get_register_size(REG_D0);
uint32_t regsize = get_register_size(op2.reg);
uint32_t dataSizeInBytes = GetDataTypeSize(instr.dataType) / 8;
for (unsigned int i = 0; i < reglist.size; i++)
{
uint32_t curOffset = i * dataSizeInBytes;
uint32_t curregind = REG_D0 + reglist.start + i;

il.AddInstruction(il.SetRegister(dregsize, curregind,
il.Load(dataSizeInBytes, il.Add(regsize, ILREG(op2), il.Const(regsize, curOffset)))));
}
if (op2.flags.wb)
{
il.AddInstruction(il.SetRegister(
regsize, op2.reg, il.Add(regsize, ILREG(op2), il.Const(regsize, dataSizeInBytes * reglist.size))));
}
}
});
break;
default:
//printf("Instruction: %s\n", get_operation(instr.operation));
ConditionExecute(il, instr.cond, il.Unimplemented());
Expand Down