Analysis

It’s a specific analysis of the nemu code. To make typing easier I use English.

First, I really need to know how make_helper and make_helper_v work.

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
70
71
72
73
74
75
76
77
// in 'nemu/include/cpu/helper.h'
#ifndef __HELPER_H__
#define __HELPER_H__

#include "nemu.h"
#include "cpu/decode/operand.h"

/* All function defined with 'make_helper' return the length of the operation. */
#define make_helper(name) int name(swaddr_t eip)

static inline uint32_t instr_fetch(swadrr_t addr, size_t len)
{
return swaddr_read(addr, len); // instr_fetch equals swaddr_read, read memory
}

static int len;

static inline int idex(swaddr_t eip, int (*decode)(swaddr_t), void (*execute)(void))
{
/* eip is pointing to the opcode */
len = decode(eip + 1);
execute();
return len + 1; // "1" for opcode
}

/*
in 'nemu/include/cpu/exec/helper.h' there is a reference of idex:
idex(eip, concat4(decode_, type, _, SUFFIX), do_execute);
do_execute is a self-defined function, defined in every instruction's .h template files.

see what's concat4:
in 'nemu/include/macro.h':

#define str_temp(x) #x
#define str(x) str_temp(x)

#define concat_temp(x, y) x ## y
#define concat(x, y) concat_temp(x, y)
#define concat3(x, y, z) concat(concat(x, y), z)
#define concat4(x, y, z, w) concat3(concat(x, y), z, w)
#define concat5(x, y, z, v, w) concat4(concat(x, y), z, v, w)

It remains to be a problem.

*/

static inline int get_instr_len()
{
return len + 1;
}

extern Operands ops_decoded;

#define op_src (&ops_decoded.src)
#define op_src2 (&ops_decoded.src2)
#define op_dest (&ops_decoded.dest)

#endif


/*
So what's Operands?
in 'nemu/include/cpu/decode/operand.h':

typedef struct {
uint32_t opcode;
bool is_data_size_16;
Operand src, dest, src2;
} Operands;

About the use of is_data_size_16:

I guess it probably be like this: ops_decoded.is_data_size_16 ? concat(name, _w) : concat(name, _l).

And src and dest and src2... it seems reasonable now.

*/

Here is Operand:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef struct {
uint32_t type;
size_t size;
union {
uint32_t reg;
struct {
swaddr_t addr;
uint8_t sreg;
};
uint32_t imm;
int32_t simm;
};
uint32_t val;
char str[OP_STR_SIZE];
} Operand;