mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-07 17:43:53 +02:00
Work on C0 index func
This commit is contained in:
@@ -575,6 +575,27 @@ func (f *Function) Or(a, b, dest Register) {
|
||||
f.AddTrailingComment(dest, "=", a, "|", b, "(bitwise)")
|
||||
}
|
||||
|
||||
func (f *Function) And(a, b, dest Register) {
|
||||
if f.ISA.Goarch == ARM64 {
|
||||
f.instr("VAND", a.ARMFullWidth(), b.ARMFullWidth(), dest.ARMFullWidth())
|
||||
} else {
|
||||
if f.ISA.Bits == 128 {
|
||||
switch dest.Name {
|
||||
case b.Name:
|
||||
f.instr("PAND", a, b)
|
||||
case a.Name:
|
||||
f.instr("PAND", b, a)
|
||||
default:
|
||||
f.CopyRegister(b, dest)
|
||||
f.instr("PAND", a, dest)
|
||||
}
|
||||
} else {
|
||||
f.instr("VAND", a, b, dest)
|
||||
}
|
||||
}
|
||||
f.AddTrailingComment(dest, "=", a, "&", b, "(bitwise)")
|
||||
}
|
||||
|
||||
func (f *Function) ClearRegisterToZero(r Register) {
|
||||
defer func() { f.AddTrailingComment("set", r, "to zero") }()
|
||||
if f.ISA.Goarch == ARM64 {
|
||||
@@ -959,9 +980,12 @@ func (s *Function) AddTrailingComment(x ...any) {
|
||||
}
|
||||
|
||||
func val_repr_for_arithmetic(val any) (ans string) {
|
||||
switch val.(type) {
|
||||
switch v := val.(type) {
|
||||
case int:
|
||||
return fmt.Sprintf("$%d", val)
|
||||
if v < 0 {
|
||||
return fmt.Sprintf("$%d", v)
|
||||
}
|
||||
return fmt.Sprintf("$0x%x", v)
|
||||
case string:
|
||||
return val.(string)
|
||||
case fmt.Stringer:
|
||||
@@ -1279,6 +1303,47 @@ func (s *State) indexbyte2() {
|
||||
|
||||
}
|
||||
|
||||
func (s *State) indexc0_body(f *Function) {
|
||||
lower := f.Vec()
|
||||
upper := f.Vec()
|
||||
del := f.Vec()
|
||||
f.Set1Epi8(-1, lower)
|
||||
f.Set1Epi8(int(' '), upper)
|
||||
f.Set1Epi8(0x7f, del)
|
||||
|
||||
test_bytes := func(pos, test_ans Register, aligned bool, byte_found_label string) {
|
||||
bytes_to_test := f.Vec()
|
||||
defer f.ReleaseReg(bytes_to_test)
|
||||
temp := f.Vec()
|
||||
defer f.ReleaseReg(temp)
|
||||
|
||||
if aligned {
|
||||
f.LoadPointerAligned(pos, bytes_to_test)
|
||||
} else {
|
||||
f.LoadPointerUnaligned(pos, bytes_to_test)
|
||||
}
|
||||
f.CmpEqEpi8(bytes_to_test, del, test_ans)
|
||||
f.CmpLtEpi8(bytes_to_test, upper, temp)
|
||||
f.CmpGtEpi8(bytes_to_test, lower, bytes_to_test)
|
||||
f.And(temp, bytes_to_test, bytes_to_test)
|
||||
f.Or(test_ans, bytes_to_test, test_ans)
|
||||
f.JumpIfNonZero(test_ans, byte_found_label)
|
||||
}
|
||||
s.index_func(f, test_bytes)
|
||||
}
|
||||
|
||||
func (s *State) indexc0() {
|
||||
f := s.NewFunction("index_c0_asm", "Find the index of a C0 control code", []FunctionParam{{"data", ByteSlice}}, []FunctionParam{{"ans", types.Int}})
|
||||
if s.ISA.HasSIMD {
|
||||
s.indexc0_body(f)
|
||||
}
|
||||
f = s.NewFunction("index_c0_string_asm", "Find the index of a C0 control code", []FunctionParam{{"data", types.String}}, []FunctionParam{{"ans", types.Int}})
|
||||
if s.ISA.HasSIMD {
|
||||
s.indexc0_body(f)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *State) Generate() {
|
||||
s.test_load()
|
||||
s.test_set1_epi8()
|
||||
@@ -1289,6 +1354,7 @@ func (s *State) Generate() {
|
||||
s.test_count_to_match()
|
||||
|
||||
s.indexbyte2()
|
||||
s.indexc0()
|
||||
|
||||
s.OutputFunction()
|
||||
}
|
||||
|
||||
@@ -169,6 +169,42 @@ func TestSIMDStringOps(t *testing.T) {
|
||||
tbs(addr, datalen)
|
||||
}
|
||||
}
|
||||
|
||||
c0test := func(haystack []byte) {
|
||||
var actual int
|
||||
safe_haystack := append(bytes.Repeat([]byte{'<'}, 64), haystack...)
|
||||
safe_haystack = append(safe_haystack, bytes.Repeat([]byte{'>'}, 64)...)
|
||||
haystack = safe_haystack[64 : 64+len(haystack)]
|
||||
expected := index_c0_scalar(haystack)
|
||||
|
||||
for _, sz := range sizes {
|
||||
switch sz {
|
||||
case 16:
|
||||
actual = index_c0_asm_128(haystack)
|
||||
case 32:
|
||||
actual = index_c0_asm_256(haystack)
|
||||
}
|
||||
if actual != expected {
|
||||
t.Fatalf("Failed to find C0 char in: %#v (%d != %d) at size: %d", string(haystack), expected, actual, sz)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
c0tests := func(h string) {
|
||||
c0test([]byte(h))
|
||||
for _, sz := range []int{16, 32, 64, 79} {
|
||||
q := strings.Repeat(" ", sz) + h
|
||||
c0test([]byte(q))
|
||||
}
|
||||
}
|
||||
|
||||
c0tests("")
|
||||
c0tests("a")
|
||||
c0tests("a\x00")
|
||||
c0tests("afsgdfg\x7f")
|
||||
c0tests("a\nfgdfgd\r")
|
||||
c0tests("afgd\rfgd\t")
|
||||
}
|
||||
|
||||
func TestIntrinsics(t *testing.T) {
|
||||
|
||||
@@ -21,3 +21,21 @@ func index_byte2_string_scalar(data string, a, b byte) int {
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func index_c0_scalar(data []byte) int {
|
||||
for i := 0; i < len(data); i++ {
|
||||
if data[i] == 0x7f || data[i] < ' ' {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func index_c0_string_scalar(data string) int {
|
||||
for i := 0; i < len(data); i++ {
|
||||
if data[i] == 0x7f || data[i] < ' ' {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user