-
Notifications
You must be signed in to change notification settings - Fork 0
/
decode.c
70 lines (60 loc) · 2.23 KB
/
decode.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
* This file is part of arm-sim: http://madscientistroom.org/arm-sim
*
* Copyright (c) 2010 Randy Thelen. All rights reserved, and all wrongs
* reversed. (See the file COPYRIGHT for details.)
*/
#include "sim.h"
#include "arm.h"
arm_cond_t arm_decode_cond(reg instr)
{
return IBITS(28,4);
}
arm_instr_t arm_decode_instr(reg instr)
{
arm_instr_t t = ARM_INSTR_ILLEGAL;
if (IBITS(24, 4) == 0xF) return (ARM_INSTR_SWI);
if (IBITS(25, 3) == BPAT3(1,0,1)) return (ARM_INSTR_B);
if (IBITS(26, 2) == BPAT2(0,0)) {
if (!IBIT(25) && !IBIT(4)) return (ARM_INSTR_AND + IBITS(21, 4));
if (!IBIT(25) && IBIT(4) && !IBIT(7)) return (ARM_INSTR_AND + IBITS(21, 4));
if ( IBIT(25)) return (ARM_INSTR_AND + IBITS(21, 4));
}
if (IBITS(22,6) == 0 && IBITS(4,4) == 9) return ARM_INSTR_MUL;
if (IBITS(23,5) == 1 && IBITS(4,4) == 9) return ARM_INSTR_MULL;
if (IBITS(25,3) == 2) {
/* Load/Store 12bit imm */
if (IBIT(20)) return (ARM_INSTR_LDR);
else return (ARM_INSTR_STR);
}
if (IBITS(25,3) == 3 && !IBIT(4)) {
if (IBIT(20)) return (ARM_INSTR_LDR);
else return (ARM_INSTR_STR);
}
if (!IBITS(25,3) && IBIT(7) && IBIT(4)) {
if (IBIT(20)) {
if (IBIT(22)) {
if ( IBIT(6) && IBIT(5)) return (ARM_INSTR_LDSH);
if ( IBIT(6) && !IBIT(5)) return (ARM_INSTR_LDSB);
if (!IBIT(6) && IBIT(5)) return (ARM_INSTR_LDUH);
}
if (!IBIT(22) && !IBITS(8,4)) {
if ( IBIT(6) && IBIT(5)) return (ARM_INSTR_LDSH);
if ( IBIT(6) && !IBIT(5)) return (ARM_INSTR_LDSB);
if (!IBIT(6) && IBIT(5)) return (ARM_INSTR_LDUH);
}
} else {
if (IBIT(22)) {
if (!IBIT(6) && IBIT(5)) return (ARM_INSTR_STH);
}
if (!IBIT(22) && !IBITS(8,4)) {
if (!IBIT(6) && IBIT(5)) return (ARM_INSTR_STH);
}
}
}
if (IBITS(25, 3) == BPAT3(1,0,0)) {
if (IBIT(20)) return (ARM_INSTR_LDM);
else return (ARM_INSTR_STM);
}
return t;
}