Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 92ca3ba

Browse files
Mike KleinSkia Commit-Bot
authored andcommitted
JIT today's new _imm ops
- Add YmmOrLabel struct to represent the concept that many x86 instructions can take a final argument as either a register or memory address, and that they all handle them the same way. - Convert existing overloads like vmulps() to use YmmOrLabel. - upgrade some other instructions to take YmmOrLabel - use them to implement today's new _imm ops This feels like a good spot for implicit constructors, no? Change-Id: I435028acc3fbfcc16f634cfccc98fe38bbce9d19 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/263207 Reviewed-by: Mike Klein <[email protected]> Commit-Queue: Mike Klein <[email protected]>
1 parent b45558d commit 92ca3ba

File tree

3 files changed

+55
-36
lines changed

3 files changed

+55
-36
lines changed

src/core/SkVM.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,24 +1060,24 @@ namespace skvm {
10601060
this->byte(mod_rm(Mod::Direct, dst&7, y&7));
10611061
}
10621062

1063-
void Assembler::vpaddd (Ymm dst, Ymm x, Ymm y) { this->op(0x66, 0x0f,0xfe, dst,x,y); }
1064-
void Assembler::vpsubd (Ymm dst, Ymm x, Ymm y) { this->op(0x66, 0x0f,0xfa, dst,x,y); }
1065-
void Assembler::vpmulld(Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x380f,0x40, dst,x,y); }
1063+
void Assembler::vpaddd (Ymm dst, Ymm x, YmmOrLabel y) { this->op(0x66, 0x0f,0xfe, dst,x,y); }
1064+
void Assembler::vpsubd (Ymm dst, Ymm x, YmmOrLabel y) { this->op(0x66, 0x0f,0xfa, dst,x,y); }
1065+
void Assembler::vpmulld(Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x380f,0x40, dst,x,y); }
10661066

10671067
void Assembler::vpsubw (Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x0f,0xf9, dst,x,y); }
10681068
void Assembler::vpmullw(Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x0f,0xd5, dst,x,y); }
10691069

1070-
void Assembler::vpand (Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x0f,0xdb, dst,x,y); }
1071-
void Assembler::vpor (Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x0f,0xeb, dst,x,y); }
1072-
void Assembler::vpxor (Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x0f,0xef, dst,x,y); }
1073-
void Assembler::vpandn(Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x0f,0xdf, dst,x,y); }
1070+
void Assembler::vpand (Ymm dst, Ymm x, YmmOrLabel y) { this->op(0x66,0x0f,0xdb, dst,x,y); }
1071+
void Assembler::vpor (Ymm dst, Ymm x, YmmOrLabel y) { this->op(0x66,0x0f,0xeb, dst,x,y); }
1072+
void Assembler::vpxor (Ymm dst, Ymm x, YmmOrLabel y) { this->op(0x66,0x0f,0xef, dst,x,y); }
1073+
void Assembler::vpandn(Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x0f,0xdf, dst,x,y); }
10741074

1075-
void Assembler::vaddps(Ymm dst, Ymm x, Ymm y) { this->op(0,0x0f,0x58, dst,x,y); }
1076-
void Assembler::vsubps(Ymm dst, Ymm x, Ymm y) { this->op(0,0x0f,0x5c, dst,x,y); }
1077-
void Assembler::vmulps(Ymm dst, Ymm x, Ymm y) { this->op(0,0x0f,0x59, dst,x,y); }
1078-
void Assembler::vdivps(Ymm dst, Ymm x, Ymm y) { this->op(0,0x0f,0x5e, dst,x,y); }
1079-
void Assembler::vminps(Ymm dst, Ymm x, Ymm y) { this->op(0,0x0f,0x5d, dst,x,y); }
1080-
void Assembler::vmaxps(Ymm dst, Ymm x, Ymm y) { this->op(0,0x0f,0x5f, dst,x,y); }
1075+
void Assembler::vaddps(Ymm dst, Ymm x, YmmOrLabel y) { this->op(0,0x0f,0x58, dst,x,y); }
1076+
void Assembler::vsubps(Ymm dst, Ymm x, YmmOrLabel y) { this->op(0,0x0f,0x5c, dst,x,y); }
1077+
void Assembler::vmulps(Ymm dst, Ymm x, YmmOrLabel y) { this->op(0,0x0f,0x59, dst,x,y); }
1078+
void Assembler::vdivps(Ymm dst, Ymm x, Ymm y) { this->op(0,0x0f,0x5e, dst,x,y); }
1079+
void Assembler::vminps(Ymm dst, Ymm x, YmmOrLabel y) { this->op(0,0x0f,0x5d, dst,x,y); }
1080+
void Assembler::vmaxps(Ymm dst, Ymm x, YmmOrLabel y) { this->op(0,0x0f,0x5f, dst,x,y); }
10811081

10821082
void Assembler::vfmadd132ps(Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x380f,0x98, dst,x,y); }
10831083
void Assembler::vfmadd213ps(Ymm dst, Ymm x, Ymm y) { this->op(0x66,0x380f,0xa8, dst,x,y); }
@@ -1168,11 +1168,12 @@ namespace skvm {
11681168
this->word(this->disp32(l));
11691169
}
11701170

1171-
void Assembler::vpshufb(Ymm dst, Ymm x, Label* l) { this->op(0x66,0x380f,0x00, dst,x,l); }
1172-
void Assembler::vpaddd (Ymm dst, Ymm x, Label* l) { this->op(0x66, 0x0f,0xfe, dst,x,l); }
1173-
void Assembler::vpsubd (Ymm dst, Ymm x, Label* l) { this->op(0x66, 0x0f,0xfa, dst,x,l); }
1174-
void Assembler::vmulps (Ymm dst, Ymm x, Label* l) { this->op( 0, 0x0f,0x59, dst,x,l); }
1171+
void Assembler::op(int prefix, int map, int opcode, Ymm dst, Ymm x, YmmOrLabel y) {
1172+
y.label ? this->op(prefix,map,opcode,dst,x, y.label)
1173+
: this->op(prefix,map,opcode,dst,x, y.ymm );
1174+
}
11751175

1176+
void Assembler::vpshufb(Ymm dst, Ymm x, Label* l) { this->op(0x66,0x380f,0x00, dst,x,l); }
11761177
void Assembler::vptest(Ymm dst, Label* l) { this->op(0x66, 0x380f, 0x17, dst, (Ymm)0, l); }
11771178

11781179
void Assembler::vbroadcastss(Ymm dst, Label* l) { this->op(0x66,0x380f,0x18, dst, (Ymm)0, l); }
@@ -2296,7 +2297,11 @@ namespace skvm {
22962297
a->vfmadd132ps(dst(),r[z], r[y]); }
22972298
break;
22982299

2300+
case Op::add_f32_imm: a->vaddps(dst(), r[x], &constants[immy].label); break;
2301+
case Op::sub_f32_imm: a->vsubps(dst(), r[x], &constants[immy].label); break;
22992302
case Op::mul_f32_imm: a->vmulps(dst(), r[x], &constants[immy].label); break;
2303+
case Op::min_f32_imm: a->vminps(dst(), r[x], &constants[immy].label); break;
2304+
case Op::max_f32_imm: a->vmaxps(dst(), r[x], &constants[immy].label); break;
23002305

23012306
case Op::add_i32: a->vpaddd (dst(), r[x], r[y]); break;
23022307
case Op::sub_i32: a->vpsubd (dst(), r[x], r[y]); break;
@@ -2312,6 +2317,10 @@ namespace skvm {
23122317
case Op::bit_clear: a->vpandn(dst(), r[y], r[x]); break; // N.B. Y then X.
23132318
case Op::select : a->vpblendvb(dst(), r[z], r[y], r[x]); break;
23142319

2320+
case Op::bit_and_imm: a->vpand (dst(), r[x], &constants[immy].label); break;
2321+
case Op::bit_or_imm : a->vpor (dst(), r[x], &constants[immy].label); break;
2322+
case Op::bit_xor_imm: a->vpxor (dst(), r[x], &constants[immy].label); break;
2323+
23152324
case Op::shl_i32: a->vpslld(dst(), r[x], immy); break;
23162325
case Op::shr_i32: a->vpsrld(dst(), r[x], immy); break;
23172326
case Op::sra_i32: a->vpsrad(dst(), r[x], immy); break;

src/core/SkVM.h

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,35 @@ namespace skvm {
6666
void add(GP64, int imm);
6767
void sub(GP64, int imm);
6868

69+
struct Label {
70+
int offset = 0;
71+
enum { NotYetSet, ARMDisp19, X86Disp32 } kind = NotYetSet;
72+
std::vector<int> references;
73+
};
74+
75+
struct YmmOrLabel {
76+
Ymm ymm = ymm0;
77+
Label* label = nullptr;
78+
79+
/*implicit*/ YmmOrLabel(Ymm y) : ymm (y) { SkASSERT(!label); }
80+
/*implicit*/ YmmOrLabel(Label* l) : label(l) { SkASSERT( label); }
81+
};
82+
6983
// All dst = x op y.
7084
using DstEqXOpY = void(Ymm dst, Ymm x, Ymm y);
71-
DstEqXOpY vpand, vpor, vpxor, vpandn,
72-
vpaddd, vpsubd, vpmulld,
73-
vpsubw, vpmullw,
74-
vaddps, vsubps, vmulps, vdivps, vminps, vmaxps,
85+
DstEqXOpY vpandn,
86+
vpmulld,
87+
vpsubw, vpmullw,
88+
vdivps,
7589
vfmadd132ps, vfmadd213ps, vfmadd231ps,
7690
vpackusdw, vpackuswb,
7791
vpcmpeqd, vpcmpgtd;
7892

93+
using DstEqXOpYOrLabel = void(Ymm dst, Ymm x, YmmOrLabel y);
94+
DstEqXOpYOrLabel vpand, vpor, vpxor,
95+
vpaddd, vpsubd,
96+
vaddps, vsubps, vmulps, vminps, vmaxps;
97+
7998
// Floating point comparisons are all the same instruction with varying imm.
8099
void vcmpps(Ymm dst, Ymm x, Ymm y, int imm);
81100
void vcmpeqps (Ymm dst, Ymm x, Ymm y) { this->vcmpps(dst,x,y,0); }
@@ -93,12 +112,6 @@ namespace skvm {
93112

94113
void vpblendvb(Ymm dst, Ymm x, Ymm y, Ymm z);
95114

96-
struct Label {
97-
int offset = 0;
98-
enum { NotYetSet, ARMDisp19, X86Disp32 } kind = NotYetSet;
99-
std::vector<int> references;
100-
};
101-
102115
Label here();
103116
void label(Label*);
104117

@@ -109,17 +122,13 @@ namespace skvm {
109122
void jc (Label*);
110123
void cmp(GP64, int imm);
111124

125+
void vpshufb(Ymm dst, Ymm x, Label*);
112126
void vptest(Ymm dst, Label*);
113127

114128
void vbroadcastss(Ymm dst, Label*);
115129
void vbroadcastss(Ymm dst, Xmm src);
116130
void vbroadcastss(Ymm dst, GP64 ptr, int off); // dst = *(ptr+off)
117131

118-
void vpshufb(Ymm dst, Ymm x, Label*);
119-
void vpaddd (Ymm dst, Ymm x, Label*);
120-
void vpsubd (Ymm dst, Ymm x, Label*);
121-
void vmulps (Ymm dst, Ymm x, Label*);
122-
123132
void vmovups (Ymm dst, GP64 ptr); // dst = *ptr, 256-bit
124133
void vpmovzxwd(Ymm dst, GP64 ptr); // dst = *ptr, 128-bit, each uint16_t expanded to int
125134
void vpmovzxbd(Ymm dst, GP64 ptr); // dst = *ptr, 64-bit, each uint8_t expanded to int
@@ -229,6 +238,7 @@ namespace skvm {
229238

230239
// dst = op(x,label) or op(label)
231240
void op(int prefix, int map, int opcode, Ymm dst, Ymm x, Label* l);
241+
void op(int prefix, int map, int opcode, Ymm dst, Ymm x, YmmOrLabel);
232242

233243
// *ptr = ymm or ymm = *ptr, depending on opcode.
234244
void load_store(int prefix, int map, int opcode, Ymm ymm, GP64 ptr);

tests/SkVMTest.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ DEF_TEST(SkVM, r) {
188188
uint32_t src[9];
189189
uint32_t dst[SK_ARRAY_COUNT(src)];
190190

191-
test_interpreter_only(r, std::move(program), [&](const skvm::Program& program) {
191+
test_jit_and_interpreter(r, std::move(program), [&](const skvm::Program& program) {
192192
for (int i = 0; i < (int)SK_ARRAY_COUNT(src); i++) {
193193
src[i] = 0xbb007733;
194194
dst[i] = 0xffaaccee;
@@ -220,7 +220,7 @@ DEF_TEST(SkVM, r) {
220220
test_8888(SrcoverBuilder_I32{}.done("srcover_i32"));
221221
test_8888(SrcoverBuilder_I32_SWAR{}.done("srcover_i32_SWAR"));
222222

223-
test_interpreter_only(r, SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::G8}.done(),
223+
test_jit_and_interpreter(r, SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::G8}.done(),
224224
[&](const skvm::Program& program) {
225225
uint32_t src[9];
226226
uint8_t dst[SK_ARRAY_COUNT(src)];
@@ -387,7 +387,7 @@ DEF_TEST(SkVM_bitops, r) {
387387
b.store32(ptr, x);
388388
}
389389

390-
test_interpreter_only(r, b.done(), [&](const skvm::Program& program) {
390+
test_jit_and_interpreter(r, b.done(), [&](const skvm::Program& program) {
391391
int x = 0x42;
392392
program.eval(1, &x);
393393
REPORTER_ASSERT(r, x == 0x7fff'ffff);
@@ -472,7 +472,7 @@ DEF_TEST(SkVM_cmp_f32, r) {
472472
b.store32(b.varying<int>(), m);
473473
}
474474

475-
test_interpreter_only(r, b.done(), [&](const skvm::Program& program) {
475+
test_jit_and_interpreter(r, b.done(), [&](const skvm::Program& program) {
476476
float in[] = { 0,1,2,3,4,5,6,7,8,9 };
477477
int out[SK_ARRAY_COUNT(in)];
478478

0 commit comments

Comments
 (0)