Skip to content

Commit f4b584a

Browse files
chenjKexyBiscuit
authored andcommitted
AOSCOS: Optimize clear_page
Signed-off-by: chenj <[email protected]> Signed-off-by: Kexy Biscuit <[email protected]>
1 parent bfa8002 commit f4b584a

File tree

5 files changed

+56
-1
lines changed

5 files changed

+56
-1
lines changed

arch/mips/include/asm/uasm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ void uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)
4242
#define Ip_s3s1s2(op) \
4343
void uasm_i##op(u32 **buf, int a, int b, int c)
4444

45+
#define Ip_u4u2u1s3(op) \
46+
void uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c, \
47+
unsigned int d)
48+
4549
#define Ip_u2u1s3(op) \
4650
void uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
4751

@@ -159,6 +163,7 @@ Ip_u2s3u1(_sd);
159163
Ip_u3u1u2(_seleqz);
160164
Ip_u3u1u2(_selnez);
161165
Ip_u2s3u1(_sh);
166+
Ip_u4u2u1s3(_gssq);
162167
Ip_u2u1u3(_sll);
163168
Ip_u3u2u1(_sllv);
164169
Ip_s3s1s2(_slt);

arch/mips/include/uapi/asm/inst.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ enum ddivu_op {
137137
ddivu_dmodu_op = 0x3,
138138
};
139139

140+
/*
141+
* func field of spec opcode.
142+
*/
143+
enum swc2_op {
144+
gssq_op = 0x20,
145+
};
146+
140147
/*
141148
* rt field of bcond opcodes.
142149
*/

arch/mips/mm/page.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,11 @@ static void set_prefetch_parameters(void)
206206
else if (cpu_has_cache_cdex_p)
207207
cache_line_size = cpu_dcache_line_size();
208208
}
209+
210+
#ifdef CONFIG_CPU_LOONGSON3
211+
clear_word_size = 16;
212+
#endif
213+
209214
/*
210215
* Too much unrolling will overflow the available space in
211216
* clear_space_array / copy_page_array.
@@ -220,11 +225,15 @@ static void set_prefetch_parameters(void)
220225

221226
static void build_clear_store(u32 **buf, int off)
222227
{
228+
#ifdef CONFIG_CPU_LOONGSON3
229+
uasm_i_gssq(buf, ZERO, ZERO, off, A0);
230+
#else
223231
if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg) {
224232
uasm_i_sd(buf, GPR_ZERO, off, GPR_A0);
225233
} else {
226234
uasm_i_sw(buf, GPR_ZERO, off, GPR_A0);
227235
}
236+
#endif
228237
}
229238

230239
static inline void build_clear_pref(u32 **buf, int off)

arch/mips/mm/uasm-mips.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#define RT_SH 16
2828
#define SCIMM_MASK 0xfffff
2929
#define SCIMM_SH 6
30+
#define RZ_MASK 0x1f
31+
#define RZ_SH 0
32+
#define RC_MASK 0x1ff
33+
#define RC_SH 6
3034

3135
/* This macro sets the non-variable bits of an instruction. */
3236
#define M(a, b, c, d, e, f) \
@@ -203,6 +207,7 @@ static const struct insn insn_table[insn_invalid] = {
203207
[insn_xor] = {M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD},
204208
[insn_xori] = {M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM},
205209
[insn_yield] = {M(spec3_op, 0, 0, 0, 0, yield_op), RS | RD},
210+
[insn_gssq] = {M(swc2_op, 0, 0, 0, 0, gssq_op), RT | RS | RZ | RC},
206211
};
207212

208213
#undef M
@@ -225,6 +230,21 @@ static inline u32 build_jimm(u32 arg)
225230
return (arg >> 2) & JIMM_MASK;
226231
}
227232

233+
static inline u32 build_rz(u32 arg)
234+
{
235+
WARN(arg & ~RZ_MASK, KERN_WARNING "Micro-assembler field overflow\n");
236+
237+
return (arg & RZ_MASK) << RZ_SH;
238+
}
239+
240+
static inline u32 build_rc(s32 arg)
241+
{
242+
WARN((arg >> 4) > 0xff ||
243+
(arg >> 4) < -0x100, KERN_WARNING "Micro-assembler field overflow\n");
244+
245+
return ((arg >> 4) & RC_MASK) << RC_SH;
246+
}
247+
228248
/*
229249
* The order of opcode arguments is implicitly left to right,
230250
* starting with RS and ending with FUNC or IMM.
@@ -252,6 +272,10 @@ static void build_insn(u32 **buf, enum opcode opc, ...)
252272
op |= build_rd(va_arg(ap, u32));
253273
if (ip->fields & RE)
254274
op |= build_re(va_arg(ap, u32));
275+
if (ip->fields & RZ)
276+
op |= build_rz(va_arg(ap, u32));
277+
if (ip->fields & RC)
278+
op |= build_rc(va_arg(ap, s32));
255279
if (ip->fields & SIMM)
256280
op |= build_simm(va_arg(ap, s32));
257281
if (ip->fields & UIMM)

arch/mips/mm/uasm.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ enum fields {
2626
SET = 0x200,
2727
SCIMM = 0x400,
2828
SIMM9 = 0x800,
29+
RZ = 0x1000,
30+
RC = 0x2000
2931
};
3032

3133
#define OP_MASK 0x3f
@@ -65,7 +67,7 @@ enum opcode {
6567
insn_sllv, insn_slt, insn_slti, insn_sltiu, insn_sltu, insn_sra,
6668
insn_srav, insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync,
6769
insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait,
68-
insn_wsbh, insn_xor, insn_xori, insn_yield,
70+
insn_wsbh, insn_xor, insn_xori, insn_yield, insn_gssq,
6971
insn_invalid /* insn_invalid must be last */
7072
};
7173

@@ -198,6 +200,13 @@ Ip_u2s3u1(op) \
198200
} \
199201
UASM_EXPORT_SYMBOL(uasm_i##op);
200202

203+
#define I_u4u2u1s3(op) \
204+
Ip_u4u2u1s3(op) \
205+
{ \
206+
build_insn(buf, insn##op, d, b, a, c); \
207+
} \
208+
UASM_EXPORT_SYMBOL(uasm_i##op);
209+
201210
#define I_u2u1s3(op) \
202211
Ip_u2u1s3(op) \
203212
{ \
@@ -356,6 +365,7 @@ I_u2s3u1(_sd)
356365
I_u3u1u2(_seleqz)
357366
I_u3u1u2(_selnez)
358367
I_u2s3u1(_sh)
368+
I_u4u2u1s3(_gssq)
359369
I_u2u1u3(_sll)
360370
I_u3u2u1(_sllv)
361371
I_s3s1s2(_slt)

0 commit comments

Comments
 (0)