1        .syntax unified
2        .cpu cortex-m4
3        .fpu fpv4-sp-d16
4        .text
5        .align  1
6        .thumb
7        .thumb_func
8        .global _start
9_start:
10        @ LDM CASE #1 (used when rx is in upper_list)
11        @ ldm rx, {...} ->
12        @ ldm rx!, {lower_list}
13        @ ldm rx,  {upper_list}
14        @ b.w
15        ldm.w r9, {r1-r9}
16
17        @ LDM CASE #1 bis (used when rx is in upper_list and pc is
18        @ in reglist)
19        @ ldm rx, {...} ->
20        @ ldm rx!, {lower_list}
21        @ ldm rx,  {upper_list}
22        ldm.w r9, {r1-r9, pc}
23
24        @ LDM CASE #2 (used when rx is not in upper_list)
25        @ ldm rx, {...} ->
26        @ mov ry, rx where ry is the lowest register from upper_list
27        @ ldm ry!, {lower_list}
28        @ ldm ry,  {upper_list}
29        @ b.w
30        ldm.w r0, {r1-r9}
31
32        @ LDM CASE #2 bis (used when rx is in lower_list)
33        @ ldm rx, {...} ->
34        @ mov ry, rx where ry is the lowest register from upper_list
35        @ ldm ry!, {lower_list}
36        @ ldm ry,  {upper_list}
37        @ b.w
38        ldm.w r1, {r1-r9}
39
40        @ LDM CASE #2 ter (used when rx is not in upper_list and pc is
41        @ in reglist)
42        @ ldm rx, {...} ->
43        @ mov ry, rx where ry is the lowest register from upper_list
44        @ ldm ry!, {lower_list}
45        @ ldm ry,  {upper_list}
46        ldm.w r0, {r1-r9, pc}
47
48        @ LDM CASE #2 quater (used when rx is in lower_list and pc is
49        @ in reglist)
50        @ ldm rx, {...} ->
51        @ mov ry, rx where ry is the lowest register from upper_list
52        @ ldm ry!, {lower_list}
53        @ ldm ry,  {upper_list}
54        ldm.w r1, {r1-r9, pc}
55
56        @ LDM CASE #3 (used when rx is not in upper_list)
57        @ ldm rx, {...} ->
58        @ ldm rx!, {lower_list}
59        @ ldm rx!, {upper_list}
60        @ b.w
61        @ Write-back variant are unpredictable when rx appears also in
62        @ the loaded registers
63        ldm.w r0!, {r1-r9}
64
65        @ LDM CASE #3 bis (used when rx is not in upper_list and pc is
66        @ in reglist)
67        @ ldm rx, {...} ->
68        @ ldm rx!, {lower_list}
69        @ ldm rx!, {upper_list}
70        ldm.w r0!, {r1-r9, pc}
71
72        @ LDM CASE #4 (used when pc is not in reglist and rx is in
73        @ lower_list)
74        @ ldmb rx, {...} ->
75        @ ldmb rx!, {upper_list}
76        @ ldmb rx,  {lower_list}
77        ldmdb.w r1, {r1-r9}
78
79        @ LDM CASE #5 (used when pc is not in reglist and rx is not in
80        @ lower_list)
81        @ It looks like it this mean that it could be in upper_list or not
82        @ ldmdb rx, {...} ->
83        @ mov ry, rx where ry is the lowest register from lower_list
84        @ ldmdb ry!, {upper_list}
85        @ ldmdb ry , {lower_list}
86        @ b.w
87        ldmdb.w sl, {r1-r9}
88
89        @ LDM CASE #5 bis (used when pc is not in reglist and rx is in
90        @ upper_list)
91        @ ldmdb rx, {...} ->
92        @ mov ry, rx where ry is the lowest register from lower_list
93        @ ldmdb ry!, {upper_list}
94        @ ldmdb ry , {lower_list}
95        @ b.w
96        ldmdb.w r9, {r1-r9}
97
98        @ LDM CASE #6 (used when pc is in reglist and rx is in
99        @ upper_list)
100        @ ldmdb rx, {...} ->
101        @ sub rx, rx, #size (lower_list + upper_list)
102        @ ldm rx!, {lower_list}
103        @ ldm rx,  {upper_list}
104        @ This case reverses the load order
105        ldmdb.w r9, {r1-r9, pc}
106
107        @ LDM CASE #6 bis (used when pc is in reglist and rx is in
108        @ lower_list)
109        @ ldmdb rx, {...} ->
110        @ sub rx, rx, #size (lower_list + upper_list)
111        @ ldm rx!, {lower_list}
112        @ ldm rx,  {upper_list}
113        ldmdb.w r1, {r1-r9, pc}
114
115        @ LDM CASE #7 (used when pc is in reglist and rx is not in
116        @ upper_list)
117        @ ldmdb rx, {...} ->
118        @ sub ry, rx, #size (lower_list + upper_list) where ry is the lowest
119        @ register of the upper list
120        @ ldm ry!, {lower_list}
121        @ ldm ry , {upper_list}
122        @ This case reverses the load order
123        ldmdb.w r0, {r1-r9, pc}
124
125        @ LDM CASE #8 (used when pc is in not in reglist)
126        @ ldmdb rx!, {...} ->
127        @ ldm rx!, {upper_list}
128        @ ldm rx!, {lower_list}
129        @ b.w
130        ldmdb.w r0!, {r1-r9}
131
132        @ LDM CASE #9 (Used when pc is in reglist)
133        @ ldmdb rx!, {...} ->
134        @ sub rx, rx, #size (lower_list + upper_list)
135        @ mov ry, rx where ry is the lowest register from upper_list
136        @ ldm ry!, {lower_list}
137        @ ldm ry , {upper_list}
138        ldmdb.w r0!, {r1-r9, pc}
139
140        @ POP CASE #1 (list does not include pc)
141        @ pop {...} -> pop {lower_list} pop {upper_list}
142        @ b.w
143        pop {r0-r9}
144
145        @ POP CASE #2 (list includes PC)
146        @ pop {...} -> pop {lower_list} pop {upper_list}
147        pop {r0-r9, pc}
148