0001
0002
0003
0004
0005
0006
0007 #ifdef __KERNEL__
0008 #include <linux/linkage.h>
0009 #include <asm/visasm.h>
0010 #include <asm/asi.h>
0011 #define GLOBAL_SPARE %g7
0012 #else
0013 #define ASI_BLK_P 0xf0
0014 #define FPRS_FEF 0x04
0015 #ifdef MEMCPY_DEBUG
0016 #define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs; \
0017 clr %g1; clr %g2; clr %g3; subcc %g0, %g0, %g0;
0018 #define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs
0019 #else
0020 #define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs
0021 #define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs
0022 #endif
0023 #define GLOBAL_SPARE %g5
0024 #endif
0025
0026 #ifndef EX_LD
0027 #define EX_LD(x,y) x
0028 #endif
0029 #ifndef EX_LD_FP
0030 #define EX_LD_FP(x,y) x
0031 #endif
0032
0033 #ifndef EX_ST
0034 #define EX_ST(x,y) x
0035 #endif
0036 #ifndef EX_ST_FP
0037 #define EX_ST_FP(x,y) x
0038 #endif
0039
0040 #ifndef LOAD
0041 #define LOAD(type,addr,dest) type [addr], dest
0042 #endif
0043
0044 #ifndef STORE
0045 #define STORE(type,src,addr) type src, [addr]
0046 #endif
0047
0048 #ifndef STORE_BLK
0049 #define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_P
0050 #endif
0051
0052 #ifndef FUNC_NAME
0053 #define FUNC_NAME U3memcpy
0054 #endif
0055
0056 #ifndef PREAMBLE
0057 #define PREAMBLE
0058 #endif
0059
0060 #ifndef XCC
0061 #define XCC xcc
0062 #endif
0063
0064 .register %g2,#scratch
0065 .register %g3,#scratch
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 .text
0078 #ifndef EX_RETVAL
0079 #define EX_RETVAL(x) x
0080 __restore_fp:
0081 VISExitHalf
0082 retl
0083 nop
0084 ENTRY(U3_retl_o2_plus_g2_plus_g1_plus_1_fp)
0085 add %g1, 1, %g1
0086 add %g2, %g1, %g2
0087 ba,pt %xcc, __restore_fp
0088 add %o2, %g2, %o0
0089 ENDPROC(U3_retl_o2_plus_g2_plus_g1_plus_1_fp)
0090 ENTRY(U3_retl_o2_plus_g2_fp)
0091 ba,pt %xcc, __restore_fp
0092 add %o2, %g2, %o0
0093 ENDPROC(U3_retl_o2_plus_g2_fp)
0094 ENTRY(U3_retl_o2_plus_g2_plus_8_fp)
0095 add %g2, 8, %g2
0096 ba,pt %xcc, __restore_fp
0097 add %o2, %g2, %o0
0098 ENDPROC(U3_retl_o2_plus_g2_plus_8_fp)
0099 ENTRY(U3_retl_o2)
0100 retl
0101 mov %o2, %o0
0102 ENDPROC(U3_retl_o2)
0103 ENTRY(U3_retl_o2_plus_1)
0104 retl
0105 add %o2, 1, %o0
0106 ENDPROC(U3_retl_o2_plus_1)
0107 ENTRY(U3_retl_o2_plus_4)
0108 retl
0109 add %o2, 4, %o0
0110 ENDPROC(U3_retl_o2_plus_4)
0111 ENTRY(U3_retl_o2_plus_8)
0112 retl
0113 add %o2, 8, %o0
0114 ENDPROC(U3_retl_o2_plus_8)
0115 ENTRY(U3_retl_o2_plus_g1_plus_1)
0116 add %g1, 1, %g1
0117 retl
0118 add %o2, %g1, %o0
0119 ENDPROC(U3_retl_o2_plus_g1_plus_1)
0120 ENTRY(U3_retl_o2_fp)
0121 ba,pt %xcc, __restore_fp
0122 mov %o2, %o0
0123 ENDPROC(U3_retl_o2_fp)
0124 ENTRY(U3_retl_o2_plus_o3_sll_6_plus_0x80_fp)
0125 sll %o3, 6, %o3
0126 add %o3, 0x80, %o3
0127 ba,pt %xcc, __restore_fp
0128 add %o2, %o3, %o0
0129 ENDPROC(U3_retl_o2_plus_o3_sll_6_plus_0x80_fp)
0130 ENTRY(U3_retl_o2_plus_o3_sll_6_plus_0x40_fp)
0131 sll %o3, 6, %o3
0132 add %o3, 0x40, %o3
0133 ba,pt %xcc, __restore_fp
0134 add %o2, %o3, %o0
0135 ENDPROC(U3_retl_o2_plus_o3_sll_6_plus_0x40_fp)
0136 ENTRY(U3_retl_o2_plus_GS_plus_0x10)
0137 add GLOBAL_SPARE, 0x10, GLOBAL_SPARE
0138 retl
0139 add %o2, GLOBAL_SPARE, %o0
0140 ENDPROC(U3_retl_o2_plus_GS_plus_0x10)
0141 ENTRY(U3_retl_o2_plus_GS_plus_0x08)
0142 add GLOBAL_SPARE, 0x08, GLOBAL_SPARE
0143 retl
0144 add %o2, GLOBAL_SPARE, %o0
0145 ENDPROC(U3_retl_o2_plus_GS_plus_0x08)
0146 ENTRY(U3_retl_o2_and_7_plus_GS)
0147 and %o2, 7, %o2
0148 retl
0149 add %o2, GLOBAL_SPARE, %o0
0150 ENDPROC(U3_retl_o2_and_7_plus_GS)
0151 ENTRY(U3_retl_o2_and_7_plus_GS_plus_8)
0152 add GLOBAL_SPARE, 8, GLOBAL_SPARE
0153 and %o2, 7, %o2
0154 retl
0155 add %o2, GLOBAL_SPARE, %o0
0156 ENDPROC(U3_retl_o2_and_7_plus_GS_plus_8)
0157 #endif
0158
0159 .align 64
0160
0161
0162
0163
0164
0165
0166
0167 .globl FUNC_NAME
0168 .type FUNC_NAME,#function
0169 FUNC_NAME:
0170 srlx %o2, 31, %g2
0171 cmp %g2, 0
0172
0173
0174 tne %xcc, 5
0175 PREAMBLE
0176 mov %o0, %o4
0177
0178
0179 cmp %o2, 0
0180 be,pn %XCC, end_return
0181 or %o0, %o1, %o3
0182
0183
0184 cmp %o2, 16
0185 blu,a,pn %XCC, less_than_16
0186 or %o3, %o2, %o3
0187
0188
0189 cmp %o2, (3 * 64)
0190 blu,pt %XCC, less_than_192
0191 andcc %o3, 0x7, %g0
0192
0193
0194
0195
0196 VISEntryHalf
0197
0198
0199 andcc %o0, 0x3f, %g2
0200 be,pt %XCC, 2f
0201
0202
0203
0204
0205
0206 sub %o0, %o1, GLOBAL_SPARE
0207 sub %g2, 0x40, %g2
0208 sub %g0, %g2, %g2
0209 sub %o2, %g2, %o2
0210 andcc %g2, 0x7, %g1
0211 be,pt %icc, 2f
0212 and %g2, 0x38, %g2
0213
0214 1: subcc %g1, 0x1, %g1
0215 EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3), U3_retl_o2_plus_g2_plus_g1_plus_1)
0216 EX_ST_FP(STORE(stb, %o3, %o1 + GLOBAL_SPARE), U3_retl_o2_plus_g2_plus_g1_plus_1)
0217 bgu,pt %XCC, 1b
0218 add %o1, 0x1, %o1
0219
0220 add %o1, GLOBAL_SPARE, %o0
0221
0222 2: cmp %g2, 0x0
0223 and %o1, 0x7, %g1
0224 be,pt %icc, 3f
0225 alignaddr %o1, %g0, %o1
0226
0227 EX_LD_FP(LOAD(ldd, %o1, %f4), U3_retl_o2_plus_g2)
0228 1: EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6), U3_retl_o2_plus_g2)
0229 add %o1, 0x8, %o1
0230 subcc %g2, 0x8, %g2
0231 faligndata %f4, %f6, %f0
0232 EX_ST_FP(STORE(std, %f0, %o0), U3_retl_o2_plus_g2_plus_8)
0233 be,pn %icc, 3f
0234 add %o0, 0x8, %o0
0235
0236 EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4), U3_retl_o2_plus_g2)
0237 add %o1, 0x8, %o1
0238 subcc %g2, 0x8, %g2
0239 faligndata %f6, %f4, %f2
0240 EX_ST_FP(STORE(std, %f2, %o0), U3_retl_o2_plus_g2_plus_8)
0241 bne,pt %icc, 1b
0242 add %o0, 0x8, %o0
0243
0244 3: LOAD(prefetch, %o1 + 0x000, #one_read)
0245 LOAD(prefetch, %o1 + 0x040, #one_read)
0246 andn %o2, (0x40 - 1), GLOBAL_SPARE
0247 LOAD(prefetch, %o1 + 0x080, #one_read)
0248 LOAD(prefetch, %o1 + 0x0c0, #one_read)
0249 LOAD(prefetch, %o1 + 0x100, #one_read)
0250 EX_LD_FP(LOAD(ldd, %o1 + 0x000, %f0), U3_retl_o2)
0251 LOAD(prefetch, %o1 + 0x140, #one_read)
0252 EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2), U3_retl_o2)
0253 LOAD(prefetch, %o1 + 0x180, #one_read)
0254 EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4), U3_retl_o2)
0255 LOAD(prefetch, %o1 + 0x1c0, #one_read)
0256 faligndata %f0, %f2, %f16
0257 EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6), U3_retl_o2)
0258 faligndata %f2, %f4, %f18
0259 EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8), U3_retl_o2)
0260 faligndata %f4, %f6, %f20
0261 EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10), U3_retl_o2)
0262 faligndata %f6, %f8, %f22
0263
0264 EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12), U3_retl_o2)
0265 faligndata %f8, %f10, %f24
0266 EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14), U3_retl_o2)
0267 faligndata %f10, %f12, %f26
0268 EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0), U3_retl_o2)
0269
0270 subcc GLOBAL_SPARE, 0x80, GLOBAL_SPARE
0271 add %o1, 0x40, %o1
0272 bgu,pt %XCC, 1f
0273 srl GLOBAL_SPARE, 6, %o3
0274 ba,pt %xcc, 2f
0275 nop
0276
0277 .align 64
0278 1:
0279 EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2), U3_retl_o2_plus_o3_sll_6_plus_0x80)
0280 faligndata %f12, %f14, %f28
0281 EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4), U3_retl_o2_plus_o3_sll_6_plus_0x80)
0282 faligndata %f14, %f0, %f30
0283 EX_ST_FP(STORE_BLK(%f16, %o0), U3_retl_o2_plus_o3_sll_6_plus_0x80)
0284 EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0285 faligndata %f0, %f2, %f16
0286 add %o0, 0x40, %o0
0287
0288 EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0289 faligndata %f2, %f4, %f18
0290 EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0291 faligndata %f4, %f6, %f20
0292 EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0293 subcc %o3, 0x01, %o3
0294 faligndata %f6, %f8, %f22
0295 EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14), U3_retl_o2_plus_o3_sll_6_plus_0x80)
0296
0297 faligndata %f8, %f10, %f24
0298 EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0), U3_retl_o2_plus_o3_sll_6_plus_0x80)
0299 LOAD(prefetch, %o1 + 0x1c0, #one_read)
0300 faligndata %f10, %f12, %f26
0301 bg,pt %XCC, 1b
0302 add %o1, 0x40, %o1
0303
0304
0305 2:
0306 EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2), U3_retl_o2_plus_o3_sll_6_plus_0x80)
0307 faligndata %f12, %f14, %f28
0308 EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4), U3_retl_o2_plus_o3_sll_6_plus_0x80)
0309 faligndata %f14, %f0, %f30
0310 EX_ST_FP(STORE_BLK(%f16, %o0), U3_retl_o2_plus_o3_sll_6_plus_0x80)
0311 EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0312 faligndata %f0, %f2, %f16
0313 EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0314 faligndata %f2, %f4, %f18
0315 EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0316 faligndata %f4, %f6, %f20
0317 EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0318 faligndata %f6, %f8, %f22
0319 EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0320 faligndata %f8, %f10, %f24
0321 cmp %g1, 0
0322 be,pt %XCC, 1f
0323 add %o0, 0x40, %o0
0324 EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0325 1: faligndata %f10, %f12, %f26
0326 faligndata %f12, %f14, %f28
0327 faligndata %f14, %f0, %f30
0328 EX_ST_FP(STORE_BLK(%f16, %o0), U3_retl_o2_plus_o3_sll_6_plus_0x40)
0329 add %o0, 0x40, %o0
0330 add %o1, 0x40, %o1
0331 membar #Sync
0332
0333
0334
0335
0336
0337
0338
0339 and %o2, 0x3f, %o2
0340 andcc %o2, 0x38, %g2
0341 be,pn %XCC, 2f
0342 subcc %g2, 0x8, %g2
0343 be,pn %XCC, 2f
0344 cmp %g1, 0
0345
0346 sub %o2, %g2, %o2
0347 be,a,pt %XCC, 1f
0348 EX_LD_FP(LOAD(ldd, %o1 + 0x00, %f0), U3_retl_o2_plus_g2)
0349
0350 1: EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f2), U3_retl_o2_plus_g2)
0351 add %o1, 0x8, %o1
0352 subcc %g2, 0x8, %g2
0353 faligndata %f0, %f2, %f8
0354 EX_ST_FP(STORE(std, %f8, %o0), U3_retl_o2_plus_g2_plus_8)
0355 be,pn %XCC, 2f
0356 add %o0, 0x8, %o0
0357 EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f0), U3_retl_o2_plus_g2)
0358 add %o1, 0x8, %o1
0359 subcc %g2, 0x8, %g2
0360 faligndata %f2, %f0, %f8
0361 EX_ST_FP(STORE(std, %f8, %o0), U3_retl_o2_plus_g2_plus_8)
0362 bne,pn %XCC, 1b
0363 add %o0, 0x8, %o0
0364
0365
0366
0367
0368
0369 2:
0370 cmp %o2, 0
0371 add %o1, %g1, %o1
0372 VISExitHalf
0373 be,pn %XCC, end_return
0374 sub %o0, %o1, %o3
0375
0376 andcc %g1, 0x7, %g0
0377 bne,pn %icc, 90f
0378 andcc %o2, 0x8, %g0
0379 be,pt %icc, 1f
0380 nop
0381 EX_LD(LOAD(ldx, %o1, %o5), U3_retl_o2)
0382 EX_ST(STORE(stx, %o5, %o1 + %o3), U3_retl_o2)
0383 add %o1, 0x8, %o1
0384 sub %o2, 8, %o2
0385
0386 1: andcc %o2, 0x4, %g0
0387 be,pt %icc, 1f
0388 nop
0389 EX_LD(LOAD(lduw, %o1, %o5), U3_retl_o2)
0390 EX_ST(STORE(stw, %o5, %o1 + %o3), U3_retl_o2)
0391 add %o1, 0x4, %o1
0392 sub %o2, 4, %o2
0393
0394 1: andcc %o2, 0x2, %g0
0395 be,pt %icc, 1f
0396 nop
0397 EX_LD(LOAD(lduh, %o1, %o5), U3_retl_o2)
0398 EX_ST(STORE(sth, %o5, %o1 + %o3), U3_retl_o2)
0399 add %o1, 0x2, %o1
0400 sub %o2, 2, %o2
0401
0402 1: andcc %o2, 0x1, %g0
0403 be,pt %icc, end_return
0404 nop
0405 EX_LD(LOAD(ldub, %o1, %o5), U3_retl_o2)
0406 ba,pt %xcc, end_return
0407 EX_ST(STORE(stb, %o5, %o1 + %o3), U3_retl_o2)
0408
0409 .align 64
0410
0411 less_than_192:
0412 bne,pn %XCC, 75f
0413 sub %o0, %o1, %o3
0414
0415 72:
0416 andn %o2, 0xf, GLOBAL_SPARE
0417 and %o2, 0xf, %o2
0418 1: subcc GLOBAL_SPARE, 0x10, GLOBAL_SPARE
0419 EX_LD(LOAD(ldx, %o1 + 0x00, %o5), U3_retl_o2_plus_GS_plus_0x10)
0420 EX_LD(LOAD(ldx, %o1 + 0x08, %g1), U3_retl_o2_plus_GS_plus_0x10)
0421 EX_ST(STORE(stx, %o5, %o1 + %o3), U3_retl_o2_plus_GS_plus_0x10)
0422 add %o1, 0x8, %o1
0423 EX_ST(STORE(stx, %g1, %o1 + %o3), U3_retl_o2_plus_GS_plus_0x08)
0424 bgu,pt %XCC, 1b
0425 add %o1, 0x8, %o1
0426 73: andcc %o2, 0x8, %g0
0427 be,pt %XCC, 1f
0428 nop
0429 sub %o2, 0x8, %o2
0430 EX_LD(LOAD(ldx, %o1, %o5), U3_retl_o2_plus_8)
0431 EX_ST(STORE(stx, %o5, %o1 + %o3), U3_retl_o2_plus_8)
0432 add %o1, 0x8, %o1
0433 1: andcc %o2, 0x4, %g0
0434 be,pt %XCC, 1f
0435 nop
0436 sub %o2, 0x4, %o2
0437 EX_LD(LOAD(lduw, %o1, %o5), U3_retl_o2_plus_4)
0438 EX_ST(STORE(stw, %o5, %o1 + %o3), U3_retl_o2_plus_4)
0439 add %o1, 0x4, %o1
0440 1: cmp %o2, 0
0441 be,pt %XCC, end_return
0442 nop
0443 ba,pt %xcc, 90f
0444 nop
0445
0446 75:
0447 andcc %o0, 0x7, %g1
0448 sub %g1, 0x8, %g1
0449 be,pn %icc, 2f
0450 sub %g0, %g1, %g1
0451 sub %o2, %g1, %o2
0452
0453 1: subcc %g1, 1, %g1
0454 EX_LD(LOAD(ldub, %o1, %o5), U3_retl_o2_plus_g1_plus_1)
0455 EX_ST(STORE(stb, %o5, %o1 + %o3), U3_retl_o2_plus_g1_plus_1)
0456 bgu,pt %icc, 1b
0457 add %o1, 1, %o1
0458
0459 2: add %o1, %o3, %o0
0460 andcc %o1, 0x7, %g1
0461 bne,pt %icc, 8f
0462 sll %g1, 3, %g1
0463
0464 cmp %o2, 16
0465 bgeu,pt %icc, 72b
0466 nop
0467 ba,a,pt %xcc, 73b
0468
0469 8: mov 64, %o3
0470 andn %o1, 0x7, %o1
0471 EX_LD(LOAD(ldx, %o1, %g2), U3_retl_o2)
0472 sub %o3, %g1, %o3
0473 andn %o2, 0x7, GLOBAL_SPARE
0474 sllx %g2, %g1, %g2
0475 1: EX_LD(LOAD(ldx, %o1 + 0x8, %g3), U3_retl_o2_and_7_plus_GS)
0476 subcc GLOBAL_SPARE, 0x8, GLOBAL_SPARE
0477 add %o1, 0x8, %o1
0478 srlx %g3, %o3, %o5
0479 or %o5, %g2, %o5
0480 EX_ST(STORE(stx, %o5, %o0), U3_retl_o2_and_7_plus_GS_plus_8)
0481 add %o0, 0x8, %o0
0482 bgu,pt %icc, 1b
0483 sllx %g3, %g1, %g2
0484
0485 srl %g1, 3, %g1
0486 andcc %o2, 0x7, %o2
0487 be,pn %icc, end_return
0488 add %o1, %g1, %o1
0489 ba,pt %xcc, 90f
0490 sub %o0, %o1, %o3
0491
0492 .align 64
0493
0494 less_than_16:
0495 andcc %o3, 0x3, %g0
0496 bne,pn %XCC, 90f
0497 sub %o0, %o1, %o3
0498
0499 1:
0500 subcc %o2, 4, %o2
0501 EX_LD(LOAD(lduw, %o1, %g1), U3_retl_o2_plus_4)
0502 EX_ST(STORE(stw, %g1, %o1 + %o3), U3_retl_o2_plus_4)
0503 bgu,pt %XCC, 1b
0504 add %o1, 4, %o1
0505
0506 end_return:
0507 retl
0508 mov EX_RETVAL(%o4), %o0
0509
0510 .align 32
0511 90:
0512 subcc %o2, 1, %o2
0513 EX_LD(LOAD(ldub, %o1, %g1), U3_retl_o2_plus_1)
0514 EX_ST(STORE(stb, %g1, %o1 + %o3), U3_retl_o2_plus_1)
0515 bgu,pt %XCC, 90b
0516 add %o1, 1, %o1
0517 retl
0518 mov EX_RETVAL(%o4), %o0
0519
0520 .size FUNC_NAME, .-FUNC_NAME