Refactor cgen's writeBuiltinCPUArchX86
diff --git a/internal/cgen/builtin.go b/internal/cgen/builtin.go
index 39c2f7f..d7424aa 100644
--- a/internal/cgen/builtin.go
+++ b/internal/cgen/builtin.go
@@ -449,49 +449,13 @@
 
 func (g *gen) writeBuiltinCPUArch(b *buffer, recv *a.Expr, method t.ID, args []*a.Node, sideEffectsOnly bool, depth uint32) error {
 	switch recv.MType().QID()[1] {
-	case t.IDX86SSE42Utility:
+	case t.IDX86SSE42Utility, t.IDX86M128I:
 		return g.writeBuiltinCPUArchX86(b, recv, method, args, sideEffectsOnly, depth)
 	}
 	armCRC32U32 := recv.MType().Eq(typeExprARMCRC32U32)
 	armNeon := recv.MType().Eq(typeExprARMNeon64) || recv.MType().Eq(typeExprARMNeon128)
 
 	switch method {
-	case t.IDTruncateU32, t.IDTruncateU64, t.IDStoreSlice128:
-		switch method {
-		case t.IDTruncateU32:
-			b.writes("((uint32_t)(_mm_cvtsi128_si32(")
-		case t.IDTruncateU64:
-			b.writes("((uint64_t)(_mm_cvtsi128_si64(")
-		case t.IDStoreSlice128:
-			if !sideEffectsOnly {
-				// Generate a two part expression using the comma operator: "(etc,
-				// return_empty_struct call)". The final part is a function call
-				// (to a static inline function) instead of a struct literal, to
-				// avoid a "expression result unused" compiler error.
-				b.writes("(")
-			}
-			b.writes("_mm_storeu_si128((__m128i*)(void*)(")
-			if err := g.writeExpr(b, args[0].AsArg().Value(), false, depth); err != nil {
-				return err
-			}
-			b.writes(".ptr), ")
-		}
-
-		if err := g.writeExpr(b, recv, false, depth); err != nil {
-			return err
-		}
-
-		switch method {
-		case t.IDStoreSlice128:
-			b.writes(")")
-			if !sideEffectsOnly {
-				b.writes(", wuffs_base__make_empty_struct())")
-			}
-		default:
-			b.writes(")))")
-		}
-		return nil
-
 	case t.IDCreateSlice64, t.IDCreateSlice128:
 		if armNeon {
 			switch method {
@@ -858,7 +822,62 @@
 		}
 		b.writes(")")
 		return nil
+
+	} else if strings.HasPrefix(methodStr, "store_") {
+		if !sideEffectsOnly {
+			// Generate a two part expression using the comma operator: "(etc,
+			// return_empty_struct call)". The final part is a function call
+			// (to a static inline function) instead of a struct literal, to
+			// avoid a "expression result unused" compiler error.
+			b.writes("(")
+		}
+		switch methodStr {
+		case "store_slice64":
+			b.writes("_mm_storeu_si64((void*)(")
+		case "store_slice128":
+			b.writes("_mm_storeu_si128((__m128i*)(void*)(")
+		}
+		if err := g.writeExprDotPtr(b, args[0].AsArg().Value(), false, depth); err != nil {
+			return err
+		}
+		b.writes("), ")
+		if err := g.writeExpr(b, recv, false, depth); err != nil {
+			return err
+		}
+		b.writes(")")
+		if !sideEffectsOnly {
+			b.writes(", wuffs_base__make_empty_struct())")
+		}
+		return nil
+
+	} else if strings.HasPrefix(methodStr, "truncate_u") {
+		size := methodStr[len("truncate_u"):]
+		b.printf("((uint%s_t)(_mm_cvtsi128_si%s(", size, size)
+		if err := g.writeExpr(b, recv, false, depth); err != nil {
+			return err
+		}
+		b.writes(")))")
+		return nil
 	}
+
+	b.writes(methodStr)
+	b.writes("(")
+	if err := g.writeExpr(b, recv, false, depth); err != nil {
+		return err
+	}
+	for _, o := range args {
+		b.writes(", ")
+		argAfter := ""
+		if o.AsArg().Value().MType().IsNumTypeOrIdeal() {
+			b.writes("(int32_t)(")
+			argAfter = ")"
+		}
+		if err := g.writeExpr(b, o.AsArg().Value(), false, depth); err != nil {
+			return err
+		}
+		b.writes(argAfter)
+	}
+	b.writes(")")
 	return nil
 }
 
diff --git a/lang/builtin/builtin.go b/lang/builtin/builtin.go
index d73ca44..cdb089b 100644
--- a/lang/builtin/builtin.go
+++ b/lang/builtin/builtin.go
@@ -686,9 +686,11 @@
 
 	// ---- x86_m128i
 
+	"x86_m128i.store_slice64!(a: slice base.u8)",
+	"x86_m128i.store_slice128!(a: slice base.u8)",
+
 	"x86_m128i.truncate_u32() u32",
 	"x86_m128i.truncate_u64() u64",
-	"x86_m128i.store_slice128!(a: slice base.u8)",
 
 	// TODO: generate these methods automatically?
 
diff --git a/lang/token/list.go b/lang/token/list.go
index 6773914..539f3c0 100644
--- a/lang/token/list.go
+++ b/lang/token/list.go
@@ -698,14 +698,6 @@
 
 	// --------
 
-	IDStoreSlice64  = ID(0x380)
-	IDStoreSlice128 = ID(0x381)
-	IDStoreSlice256 = ID(0x382)
-	IDStoreSlice512 = ID(0x383)
-
-	IDTruncateU32 = ID(0x388)
-	IDTruncateU64 = ID(0x389)
-
 	IDCreateSlice64  = ID(0x390)
 	IDCreateSlice128 = ID(0x391)
 )
@@ -1111,14 +1103,6 @@
 
 	IDX86M128I: "x86_m128i",
 
-	IDStoreSlice64:  "store_slice64",
-	IDStoreSlice128: "store_slice128",
-	IDStoreSlice256: "store_slice256",
-	IDStoreSlice512: "store_slice512",
-
-	IDTruncateU32: "truncate_u32",
-	IDTruncateU64: "truncate_u64",
-
 	IDCreateSlice64:  "create_slice64",
 	IDCreateSlice128: "create_slice128",
 }