Skip to content

Commit da4d7b4

Browse files
committed
libco/mips: Optimize storage for 32-bit CPUs
1 parent 772e34b commit da4d7b4

File tree

1 file changed

+128
-120
lines changed

1 file changed

+128
-120
lines changed

libco/mips.c

Lines changed: 128 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,25 @@ extern "C" {
2323
/* If we have 64-bit registers. */
2424
#define STORE_REG "sd"
2525
#define LOAD_REG "ld"
26-
#define REG_TRANSFORM(x) (x)
26+
#define _GPR_OFF(x) (x * 8)
27+
#define _VFPOFF0 (12 * 8 + 12 * 4)
28+
typedef uint64_t gpr_t;
2729
#else
2830
/* 32-bit only variant. */
2931
#define STORE_REG "sw"
3032
#define LOAD_REG "lw"
31-
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
32-
#define REG_TRANSFORM(x) (((uint64_t)(x)) << 32)
33-
#else
34-
#define REG_TRANSFORM(x) (x)
35-
#endif
33+
#define _GPR_OFF(x) (x * 4)
34+
typedef uint32_t gpr_t;
3635
#endif
36+
#define _STR(x) #x
37+
#define STR(x) _STR(x)
38+
#define GPR_OFF(x) STR(_GPR_OFF(x))
39+
/* Argument to GPR_OFF must be divisible by 4 and be >= number of saved GPR registers. */
40+
#define _FPR_OFF(x) ((x * 4) + _GPR_OFF(12))
41+
#define FPR_OFF(x) STR(_FPR_OFF(x))
42+
/* Argument to FPR_OFF must be divisible by 4 and be >= number of saved FPR registers. */
43+
#define _VFP_OFF(x) ((x * 16) + _FPR_OFF(12))
44+
#define VFP_OFF(x) STR(_VFP_OFF(x))
3745
#define HAVE_FP 1
3846
#ifdef __psp__
3947
#define HAVE_VFP 1
@@ -52,123 +60,123 @@ __asm__ (
5260
".globl _co_switch_mips\n"
5361
"co_switch_mips:\n"
5462
"_co_switch_mips:\n"
55-
STORE_REG " $s0, 0($a1)\n"
56-
STORE_REG " $s1, 8($a1)\n"
57-
STORE_REG " $s2, 0x10($a1)\n"
58-
STORE_REG " $s3, 0x18($a1)\n"
59-
STORE_REG " $s4, 0x20($a1)\n"
60-
STORE_REG " $s5, 0x28($a1)\n"
61-
STORE_REG " $s6, 0x30($a1)\n"
62-
STORE_REG " $s7, 0x38($a1)\n"
63-
STORE_REG " $gp, 0x40($a1)\n"
64-
STORE_REG " $sp, 0x48($a1)\n"
65-
STORE_REG " $fp, 0x50($a1)\n"
66-
STORE_REG " $ra, 0x58($a1)\n"
63+
STORE_REG " $s0, " GPR_OFF(0) "($a1)\n"
64+
STORE_REG " $s1, " GPR_OFF(1) "($a1)\n"
65+
STORE_REG " $s2, " GPR_OFF(2) "($a1)\n"
66+
STORE_REG " $s3, " GPR_OFF(3) "($a1)\n"
67+
STORE_REG " $s4, " GPR_OFF(4) "($a1)\n"
68+
STORE_REG " $s5, " GPR_OFF(5) "($a1)\n"
69+
STORE_REG " $s6, " GPR_OFF(6) "($a1)\n"
70+
STORE_REG " $s7, " GPR_OFF(7) "($a1)\n"
71+
STORE_REG " $gp, " GPR_OFF(8) "($a1)\n"
72+
STORE_REG " $sp, " GPR_OFF(9) "($a1)\n"
73+
STORE_REG " $fp, " GPR_OFF(10) "($a1)\n"
74+
STORE_REG " $ra, " GPR_OFF(11) "($a1)\n"
6775
#if HAVE_FP
68-
" swc1 $f20, 0x60($a1)\n"
69-
" swc1 $f21, 0x64($a1)\n"
70-
" swc1 $f22, 0x68($a1)\n"
71-
" swc1 $f23, 0x6c($a1)\n"
72-
" swc1 $f24, 0x70($a1)\n"
73-
" swc1 $f25, 0x74($a1)\n"
74-
" swc1 $f26, 0x78($a1)\n"
75-
" swc1 $f27, 0x7c($a1)\n"
76-
" swc1 $f28, 0x80($a1)\n"
77-
" swc1 $f29, 0x84($a1)\n"
78-
" swc1 $f30, 0x88($a1)\n"
76+
" swc1 $f20, " FPR_OFF(0) "($a1)\n"
77+
" swc1 $f21, " FPR_OFF(1) "($a1)\n"
78+
" swc1 $f22, " FPR_OFF(2) "($a1)\n"
79+
" swc1 $f23, " FPR_OFF(3) "($a1)\n"
80+
" swc1 $f24, " FPR_OFF(4) "($a1)\n"
81+
" swc1 $f25, " FPR_OFF(5) "($a1)\n"
82+
" swc1 $f26, " FPR_OFF(6) "($a1)\n"
83+
" swc1 $f27, " FPR_OFF(7) "($a1)\n"
84+
" swc1 $f28, " FPR_OFF(8) "($a1)\n"
85+
" swc1 $f29, " FPR_OFF(9) "($a1)\n"
86+
" swc1 $f30, " FPR_OFF(10) "($a1)\n"
7987
#endif
8088
#if HAVE_VFP
81-
" sv.q c000, 0x90($a1), wt\n"
82-
" sv.q c010, 0xa0($a1), wt\n"
83-
" sv.q c020, 0xb0($a1), wt\n"
84-
" sv.q c030, 0xc0($a1), wt\n"
85-
" sv.q c100, 0xd0($a1), wt\n"
86-
" sv.q c110, 0xe0($a1), wt\n"
87-
" sv.q c120, 0xf0($a1), wt\n"
88-
" sv.q c130, 0x100($a1), wt\n"
89-
" sv.q c200, 0x110($a1), wt\n"
90-
" sv.q c210, 0x120($a1), wt\n"
91-
" sv.q c220, 0x130($a1), wt\n"
92-
" sv.q c230, 0x140($a1), wt\n"
93-
" sv.q c300, 0x150($a1), wt\n"
94-
" sv.q c310, 0x160($a1), wt\n"
95-
" sv.q c320, 0x170($a1), wt\n"
96-
" sv.q c330, 0x180($a1), wt\n"
97-
" sv.q c400, 0x190($a1), wt\n"
98-
" sv.q c410, 0x1a0($a1), wt\n"
99-
" sv.q c420, 0x1b0($a1), wt\n"
100-
" sv.q c430, 0x1c0($a1), wt\n"
101-
" sv.q c500, 0x1d0($a1), wt\n"
102-
" sv.q c510, 0x1e0($a1), wt\n"
103-
" sv.q c520, 0x1f0($a1), wt\n"
104-
" sv.q c530, 0x200($a1), wt\n"
105-
" sv.q c600, 0x210($a1), wt\n"
106-
" sv.q c610, 0x220($a1), wt\n"
107-
" sv.q c620, 0x230($a1), wt\n"
108-
" sv.q c630, 0x240($a1), wt\n"
109-
" sv.q c700, 0x250($a1), wt\n"
110-
" sv.q c710, 0x260($a1), wt\n"
111-
" sv.q c720, 0x270($a1), wt\n"
112-
" sv.q c730, 0x280($a1), wt\n"
89+
" sv.q c000, " VFP_OFF(0) "($a1), wt\n"
90+
" sv.q c010, " VFP_OFF(1) "($a1), wt\n"
91+
" sv.q c020, " VFP_OFF(2) "($a1), wt\n"
92+
" sv.q c030, " VFP_OFF(3) "($a1), wt\n"
93+
" sv.q c100, " VFP_OFF(4) "($a1), wt\n"
94+
" sv.q c110, " VFP_OFF(5) "($a1), wt\n"
95+
" sv.q c120, " VFP_OFF(6) "($a1), wt\n"
96+
" sv.q c130, " VFP_OFF(7) "($a1), wt\n"
97+
" sv.q c200, " VFP_OFF(8) "($a1), wt\n"
98+
" sv.q c210, " VFP_OFF(9) "($a1), wt\n"
99+
" sv.q c220, " VFP_OFF(10) "($a1), wt\n"
100+
" sv.q c230, " VFP_OFF(11) "($a1), wt\n"
101+
" sv.q c300, " VFP_OFF(12) "($a1), wt\n"
102+
" sv.q c310, " VFP_OFF(13) "($a1), wt\n"
103+
" sv.q c320, " VFP_OFF(14) "($a1), wt\n"
104+
" sv.q c330, " VFP_OFF(15) "($a1), wt\n"
105+
" sv.q c400, " VFP_OFF(16) "($a1), wt\n"
106+
" sv.q c410, " VFP_OFF(17) "($a1), wt\n"
107+
" sv.q c420, " VFP_OFF(18) "($a1), wt\n"
108+
" sv.q c430, " VFP_OFF(19) "($a1), wt\n"
109+
" sv.q c500, " VFP_OFF(20) "($a1), wt\n"
110+
" sv.q c510, " VFP_OFF(21) "($a1), wt\n"
111+
" sv.q c520, " VFP_OFF(22) "($a1), wt\n"
112+
" sv.q c530, " VFP_OFF(23) "($a1), wt\n"
113+
" sv.q c600, " VFP_OFF(24) "($a1), wt\n"
114+
" sv.q c610, " VFP_OFF(25) "($a1), wt\n"
115+
" sv.q c620, " VFP_OFF(26) "($a1), wt\n"
116+
" sv.q c630, " VFP_OFF(27) "($a1), wt\n"
117+
" sv.q c700, " VFP_OFF(28) "($a1), wt\n"
118+
" sv.q c710, " VFP_OFF(29) "($a1), wt\n"
119+
" sv.q c720, " VFP_OFF(30) "($a1), wt\n"
120+
" sv.q c730, " VFP_OFF(31) "($a1), wt\n"
113121
#endif
114-
LOAD_REG " $s0, 0($a0)\n"
115-
LOAD_REG " $s1, 8($a0)\n"
116-
LOAD_REG " $s2, 0x10($a0)\n"
117-
LOAD_REG " $s3, 0x18($a0)\n"
118-
LOAD_REG " $s4, 0x20($a0)\n"
119-
LOAD_REG " $s5, 0x28($a0)\n"
120-
LOAD_REG " $s6, 0x30($a0)\n"
121-
LOAD_REG " $s7, 0x38($a0)\n"
122-
LOAD_REG " $gp, 0x40($a0)\n"
123-
LOAD_REG " $sp, 0x48($a0)\n"
124-
LOAD_REG " $fp, 0x50($a0)\n"
125-
LOAD_REG " $ra, 0x58($a0)\n"
122+
LOAD_REG " $s0, " GPR_OFF(0) "($a0)\n"
123+
LOAD_REG " $s1, " GPR_OFF(1) "($a0)\n"
124+
LOAD_REG " $s2, " GPR_OFF(2) "($a0)\n"
125+
LOAD_REG " $s3, " GPR_OFF(3) "($a0)\n"
126+
LOAD_REG " $s4, " GPR_OFF(4) "($a0)\n"
127+
LOAD_REG " $s5, " GPR_OFF(5) "($a0)\n"
128+
LOAD_REG " $s6, " GPR_OFF(6) "($a0)\n"
129+
LOAD_REG " $s7, " GPR_OFF(7) "($a0)\n"
130+
LOAD_REG " $gp, " GPR_OFF(8) "($a0)\n"
131+
LOAD_REG " $sp, " GPR_OFF(9) "($a0)\n"
132+
LOAD_REG " $fp, " GPR_OFF(10) "($a0)\n"
133+
LOAD_REG " $ra, " GPR_OFF(11) "($a0)\n"
126134
#if HAVE_FP
127-
" lwc1 $f20, 0x60($a0)\n"
128-
" lwc1 $f21, 0x64($a0)\n"
129-
" lwc1 $f22, 0x68($a0)\n"
130-
" lwc1 $f23, 0x6c($a0)\n"
131-
" lwc1 $f24, 0x70($a0)\n"
132-
" lwc1 $f25, 0x74($a0)\n"
133-
" lwc1 $f26, 0x78($a0)\n"
134-
" lwc1 $f27, 0x7c($a0)\n"
135-
" lwc1 $f28, 0x80($a0)\n"
136-
" lwc1 $f29, 0x84($a0)\n"
137-
" lwc1 $f30, 0x88($a0)\n"
135+
" lwc1 $f20, " FPR_OFF(0) "($a0)\n"
136+
" lwc1 $f21, " FPR_OFF(1) "($a0)\n"
137+
" lwc1 $f22, " FPR_OFF(2) "($a0)\n"
138+
" lwc1 $f23, " FPR_OFF(3) "($a0)\n"
139+
" lwc1 $f24, " FPR_OFF(4) "($a0)\n"
140+
" lwc1 $f25, " FPR_OFF(5) "($a0)\n"
141+
" lwc1 $f26, " FPR_OFF(6) "($a0)\n"
142+
" lwc1 $f27, " FPR_OFF(7) "($a0)\n"
143+
" lwc1 $f28, " FPR_OFF(8) "($a0)\n"
144+
" lwc1 $f29, " FPR_OFF(9) "($a0)\n"
145+
" lwc1 $f30, " FPR_OFF(10) "($a0)\n"
138146
#endif
139147
#if HAVE_VFP
140-
" lv.q c000, 0x90($a0)\n"
141-
" lv.q c010, 0xa0($a0)\n"
142-
" lv.q c020, 0xb0($a0)\n"
143-
" lv.q c030, 0xc0($a0)\n"
144-
" lv.q c100, 0xd0($a0)\n"
145-
" lv.q c110, 0xe0($a0)\n"
146-
" lv.q c120, 0xf0($a0)\n"
147-
" lv.q c130, 0x100($a0)\n"
148-
" lv.q c200, 0x110($a0)\n"
149-
" lv.q c210, 0x120($a0)\n"
150-
" lv.q c220, 0x130($a0)\n"
151-
" lv.q c230, 0x140($a0)\n"
152-
" lv.q c300, 0x150($a0)\n"
153-
" lv.q c310, 0x160($a0)\n"
154-
" lv.q c320, 0x170($a0)\n"
155-
" lv.q c330, 0x180($a0)\n"
156-
" lv.q c400, 0x190($a0)\n"
157-
" lv.q c410, 0x1a0($a0)\n"
158-
" lv.q c420, 0x1b0($a0)\n"
159-
" lv.q c430, 0x1c0($a0)\n"
160-
" lv.q c500, 0x1d0($a0)\n"
161-
" lv.q c510, 0x1e0($a0)\n"
162-
" lv.q c520, 0x1f0($a0)\n"
163-
" lv.q c530, 0x200($a0)\n"
164-
" lv.q c600, 0x210($a0)\n"
165-
" lv.q c610, 0x220($a0)\n"
166-
" lv.q c620, 0x230($a0)\n"
167-
" lv.q c630, 0x240($a0)\n"
168-
" lv.q c700, 0x250($a0)\n"
169-
" lv.q c710, 0x260($a0)\n"
170-
" lv.q c720, 0x270($a0)\n"
171-
" lv.q c730, 0x280($a0)\n"
148+
" lv.q c000, " VFP_OFF(0) "($a0)\n"
149+
" lv.q c010, " VFP_OFF(1) "($a0)\n"
150+
" lv.q c020, " VFP_OFF(2) "($a0)\n"
151+
" lv.q c030, " VFP_OFF(3) "($a0)\n"
152+
" lv.q c100, " VFP_OFF(4) "($a0)\n"
153+
" lv.q c110, " VFP_OFF(5) "($a0)\n"
154+
" lv.q c120, " VFP_OFF(6) "($a0)\n"
155+
" lv.q c130, " VFP_OFF(7) "($a0)\n"
156+
" lv.q c200, " VFP_OFF(8) "($a0)\n"
157+
" lv.q c210, " VFP_OFF(9) "($a0)\n"
158+
" lv.q c220, " VFP_OFF(10) "($a0)\n"
159+
" lv.q c230, " VFP_OFF(11) "($a0)\n"
160+
" lv.q c300, " VFP_OFF(12) "($a0)\n"
161+
" lv.q c310, " VFP_OFF(13) "($a0)\n"
162+
" lv.q c320, " VFP_OFF(14) "($a0)\n"
163+
" lv.q c330, " VFP_OFF(15) "($a0)\n"
164+
" lv.q c400, " VFP_OFF(16) "($a0)\n"
165+
" lv.q c410, " VFP_OFF(17) "($a0)\n"
166+
" lv.q c420, " VFP_OFF(18) "($a0)\n"
167+
" lv.q c430, " VFP_OFF(19) "($a0)\n"
168+
" lv.q c500, " VFP_OFF(20) "($a0)\n"
169+
" lv.q c510, " VFP_OFF(21) "($a0)\n"
170+
" lv.q c520, " VFP_OFF(22) "($a0)\n"
171+
" lv.q c530, " VFP_OFF(23) "($a0)\n"
172+
" lv.q c600, " VFP_OFF(24) "($a0)\n"
173+
" lv.q c610, " VFP_OFF(25) "($a0)\n"
174+
" lv.q c620, " VFP_OFF(26) "($a0)\n"
175+
" lv.q c630, " VFP_OFF(27) "($a0)\n"
176+
" lv.q c700, " VFP_OFF(28) "($a0)\n"
177+
" lv.q c710, " VFP_OFF(29) "($a0)\n"
178+
" lv.q c720, " VFP_OFF(30) "($a0)\n"
179+
" lv.q c730, " VFP_OFF(31) "($a0)\n"
172180
#endif
173181
" jr $ra\n"
174182
" nop\n"
@@ -184,7 +192,7 @@ __asm__ (
184192

185193
/* ASM */
186194
void co_switch_mips(cothread_t handle, cothread_t current);
187-
void store_gp(uint64_t *s);
195+
void store_gp(gpr_t *s);
188196

189197
cothread_t co_create(unsigned int size, void (*entrypoint)(void))
190198
{
@@ -200,14 +208,14 @@ cothread_t co_create(unsigned int size, void (*entrypoint)(void))
200208
if (!handle)
201209
return handle;
202210

203-
uint64_t *ptr = (uint64_t*)handle;
211+
gpr_t *ptr = (gpr_t*)handle;
204212
memset(ptr, 0, CONTEXT_SIZE);
205213
/* Non-volatiles. */
206214
/* ptr[0],..., ptr[7] -> s0,..., s7 */
207215
store_gp(&ptr[8]); /* gp */
208-
ptr[9] = REG_TRANSFORM(((uintptr_t)ptr + size - 8)); /* sp */
216+
ptr[9] = (uintptr_t)ptr + size - 8; /* sp */
209217
/* ptr[10] is fp */
210-
ptr[11] = REG_TRANSFORM((uintptr_t)entrypoint); /* ra */
218+
ptr[11] = (uintptr_t)entrypoint; /* ra */
211219
return handle;
212220
}
213221

0 commit comments

Comments
 (0)