Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
03d41243
Commit
03d41243
authored
Oct 06, 2013
by
Damien
Browse files
Add b_n opcode to inline thumb asm.
parent
b14de21f
Changes
3
Hide whitespace changes
Inline
Side-by-side
py/asmthumb.c
View file @
03d41243
...
@@ -288,6 +288,19 @@ void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8) {
...
@@ -288,6 +288,19 @@ void asm_thumb_cmp_rlo_i8(asm_thumb_t *as, uint rlo, int i8) {
asm_thumb_write_op16
(
as
,
OP_CMP_RLO_I8
(
rlo
,
i8
));
asm_thumb_write_op16
(
as
,
OP_CMP_RLO_I8
(
rlo
,
i8
));
}
}
#define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff))
void
asm_thumb_b_n
(
asm_thumb_t
*
as
,
int
label
)
{
int
dest
=
get_label_dest
(
as
,
label
);
int
rel
=
dest
-
as
->
code_offset
;
rel
-=
4
;
// account for instruction prefetch, PC is 4 bytes ahead of this instruction
if
(
SIGNED_FIT12
(
rel
))
{
asm_thumb_write_op16
(
as
,
OP_B_N
(
rel
));
}
else
{
printf
(
"asm_thumb_b_n: branch does not fit in 12 bits
\n
"
);
}
}
#define OP_BEQ_N(byte_offset) (0xd000 | (((byte_offset) >> 1) & 0x00ff))
#define OP_BEQ_N(byte_offset) (0xd000 | (((byte_offset) >> 1) & 0x00ff))
#define OP_BNE_N(byte_offset) (0xd100 | (((byte_offset) >> 1) & 0x00ff))
#define OP_BNE_N(byte_offset) (0xd100 | (((byte_offset) >> 1) & 0x00ff))
#define OP_BCS_N(byte_offset) (0xd200 | (((byte_offset) >> 1) & 0x00ff))
#define OP_BCS_N(byte_offset) (0xd200 | (((byte_offset) >> 1) & 0x00ff))
...
@@ -371,7 +384,6 @@ void asm_thumb_ite_ge(asm_thumb_t *as) {
...
@@ -371,7 +384,6 @@ void asm_thumb_ite_ge(asm_thumb_t *as) {
asm_thumb_write_op16
(
as
,
0xbfac
);
asm_thumb_write_op16
(
as
,
0xbfac
);
}
}
#define OP_B(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff))
// this could be wrong, because it should have a range of +/- 16MiB...
// this could be wrong, because it should have a range of +/- 16MiB...
#define OP_BW_HI(byte_offset) (0xf000 | (((byte_offset) >> 12) & 0x07ff))
#define OP_BW_HI(byte_offset) (0xf000 | (((byte_offset) >> 12) & 0x07ff))
#define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff))
#define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff))
...
@@ -384,7 +396,7 @@ void asm_thumb_b_label(asm_thumb_t *as, int label) {
...
@@ -384,7 +396,7 @@ void asm_thumb_b_label(asm_thumb_t *as, int label) {
// is a backwards jump, so we know the size of the jump on the first pass
// is a backwards jump, so we know the size of the jump on the first pass
// calculate rel assuming 12 bit relative jump
// calculate rel assuming 12 bit relative jump
if
(
SIGNED_FIT12
(
rel
))
{
if
(
SIGNED_FIT12
(
rel
))
{
asm_thumb_write_op16
(
as
,
OP_B
(
rel
));
asm_thumb_write_op16
(
as
,
OP_B
_N
(
rel
));
}
else
{
}
else
{
goto
large_jump
;
goto
large_jump
;
}
}
...
...
py/asmthumb.h
View file @
03d41243
...
@@ -49,6 +49,7 @@ void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src);
...
@@ -49,6 +49,7 @@ void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src);
void
asm_thumb_mov_reg_reg
(
asm_thumb_t
*
as
,
uint
reg_dest
,
uint
reg_src
);
void
asm_thumb_mov_reg_reg
(
asm_thumb_t
*
as
,
uint
reg_dest
,
uint
reg_src
);
void
asm_thumb_subs_rlo_rlo_i3
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
uint
rlo_src
,
int
i3_src
);
void
asm_thumb_subs_rlo_rlo_i3
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
uint
rlo_src
,
int
i3_src
);
void
asm_thumb_cmp_rlo_i8
(
asm_thumb_t
*
as
,
uint
rlo
,
int
i8
);
void
asm_thumb_cmp_rlo_i8
(
asm_thumb_t
*
as
,
uint
rlo
,
int
i8
);
void
asm_thumb_b_n
(
asm_thumb_t
*
as
,
int
label
);
void
asm_thumb_bgt_n
(
asm_thumb_t
*
as
,
int
label
);
void
asm_thumb_bgt_n
(
asm_thumb_t
*
as
,
int
label
);
void
asm_thumb_mov_reg_i32
(
asm_thumb_t
*
as
,
uint
reg_dest
,
machine_uint_t
i32_src
);
// convenience
void
asm_thumb_mov_reg_i32
(
asm_thumb_t
*
as
,
uint
reg_dest
,
machine_uint_t
i32_src
);
// convenience
...
...
py/emitinlinethumb.c
View file @
03d41243
...
@@ -52,7 +52,7 @@ static void emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
...
@@ -52,7 +52,7 @@ static void emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
static
int
emit_inline_thumb_count_params
(
emit_inline_asm_t
*
emit
,
int
n_params
,
py_parse_node_t
*
pn_params
)
{
static
int
emit_inline_thumb_count_params
(
emit_inline_asm_t
*
emit
,
int
n_params
,
py_parse_node_t
*
pn_params
)
{
if
(
n_params
>
4
)
{
if
(
n_params
>
4
)
{
printf
(
"SyntaxError: can only have up to
3
parameters to inline assembl
er
\n
"
);
printf
(
"SyntaxError: can only have up to
4
parameters to inline
thumb
assembl
y
\n
"
);
return
0
;
return
0
;
}
}
for
(
int
i
=
0
;
i
<
n_params
;
i
++
)
{
for
(
int
i
=
0
;
i
<
n_params
;
i
++
)
{
...
@@ -62,7 +62,7 @@ static int emit_inline_thumb_count_params(emit_inline_asm_t *emit, int n_params,
...
@@ -62,7 +62,7 @@ static int emit_inline_thumb_count_params(emit_inline_asm_t *emit, int n_params,
}
}
const
char
*
p
=
qstr_str
(
PY_PARSE_NODE_LEAF_ARG
(
pn_params
[
i
]));
const
char
*
p
=
qstr_str
(
PY_PARSE_NODE_LEAF_ARG
(
pn_params
[
i
]));
if
(
!
(
strlen
(
p
)
==
2
&&
p
[
0
]
==
'r'
&&
p
[
1
]
==
'0'
+
i
))
{
if
(
!
(
strlen
(
p
)
==
2
&&
p
[
0
]
==
'r'
&&
p
[
1
]
==
'0'
+
i
))
{
printf
(
"SyntaxError: parameter %d to inline assembler must be r%d
\n
"
,
i
,
i
);
printf
(
"SyntaxError: parameter %d to inline assembler must be r%d
\n
"
,
i
+
1
,
i
);
return
0
;
return
0
;
}
}
}
}
...
@@ -128,6 +128,9 @@ static int get_arg_label(emit_inline_asm_t *emit, qstr op, py_parse_node_t *pn_a
...
@@ -128,6 +128,9 @@ static int get_arg_label(emit_inline_asm_t *emit, qstr op, py_parse_node_t *pn_a
static
void
emit_inline_thumb_op
(
emit_inline_asm_t
*
emit
,
qstr
op
,
int
n_args
,
py_parse_node_t
*
pn_args
)
{
static
void
emit_inline_thumb_op
(
emit_inline_asm_t
*
emit
,
qstr
op
,
int
n_args
,
py_parse_node_t
*
pn_args
)
{
// TODO perhaps make two tables:
// TODO perhaps make two tables:
// one_args =
// "b", LAB, asm_thumb_b_n,
// "bgt", LAB, asm_thumb_bgt_n,
// two_args =
// two_args =
// "movs", RLO, I8, asm_thumb_movs_reg_i8
// "movs", RLO, I8, asm_thumb_movs_reg_i8
// "movw", REG, REG, asm_thumb_movw_reg_i16
// "movw", REG, REG, asm_thumb_movw_reg_i16
...
@@ -135,7 +138,14 @@ static void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, p
...
@@ -135,7 +138,14 @@ static void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, p
// "subs", RLO, RLO, I3, asm_thumb_subs_reg_reg_i3
// "subs", RLO, RLO, I3, asm_thumb_subs_reg_reg_i3
// 1 arg
// 1 arg
if
(
strcmp
(
qstr_str
(
op
),
"bgt"
)
==
0
)
{
if
(
strcmp
(
qstr_str
(
op
),
"b"
)
==
0
)
{
if
(
!
check_n_arg
(
op
,
n_args
,
1
))
{
return
;
}
int
label_num
=
get_arg_label
(
emit
,
op
,
pn_args
,
0
);
// TODO check that this succeeded, ie branch was within range
asm_thumb_b_n
(
emit
->
as
,
label_num
);
}
else
if
(
strcmp
(
qstr_str
(
op
),
"bgt"
)
==
0
)
{
if
(
!
check_n_arg
(
op
,
n_args
,
1
))
{
if
(
!
check_n_arg
(
op
,
n_args
,
1
))
{
return
;
return
;
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment