nir: Add opcodes to extract bytes or words.
authorMatt Turner <mattst88@gmail.com>
Thu, 21 Jan 2016 17:09:29 +0000 (09:09 -0800)
committerMatt Turner <mattst88@gmail.com>
Mon, 1 Feb 2016 18:43:57 +0000 (10:43 -0800)
The uint versions zero extend while the int versions sign extend.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
src/compiler/nir/nir.h
src/compiler/nir/nir_opcodes.py
src/compiler/nir/nir_opt_algebraic.py

index 3e52eae00c947db46f56cb51ef8d1ba1f02b1bfe..fa53d818fb7e75b933115baa4c71f8328a9e0707 100644 (file)
@@ -1471,6 +1471,9 @@ typedef struct nir_shader_compiler_options {
    bool lower_pack_half_2x16;
    bool lower_unpack_half_2x16;
 
+   bool lower_extract_byte;
+   bool lower_extract_word;
+
    /**
     * Does the driver support real 32-bit integers?  (Otherwise, integers
     * are simulated by floats.)
index a8bbe1a0b8270312ddaa3c0a11d6db6f903c0c2c..5f5a0efd2d6672ddecc4d1aaccaab7362472b5be 100644 (file)
@@ -536,6 +536,15 @@ dst.x = src0.x;
 dst.y = src1.x;
 """)
 
+# Byte extraction
+binop("extract_u8", tuint, "", "(uint8_t)(src0 >> (src1 * 8))")
+binop("extract_i8", tint, "", "(int8_t)(src0 >> (src1 * 8))")
+
+# Word extraction
+binop("extract_u16", tuint, "", "(uint16_t)(src0 >> (src1 * 16))")
+binop("extract_i16", tint, "", "(int16_t)(src0 >> (src1 * 16))")
+
+
 def triop(name, ty, const_expr):
    opcode(name, 0, ty, [0, 0, 0], [ty, ty, ty], "", const_expr)
 def triop_horiz(name, output_size, src1_size, src2_size, src3_size, const_expr):
index 7745b76f7ce8f11059679a6d8adebca19fc5a514..50d37ea37f10a16245e469215ca7fbcb74f55066 100644 (file)
@@ -242,6 +242,22 @@ optimizations = [
     ('bcsel', ('ult', 31, 'bits'), 'value',
               ('ubfe', 'value', 'offset', 'bits')),
     'options->lower_bitfield_extract'),
+
+   (('extract_i8', a, b),
+    ('ishr', ('ishl', a, ('imul', ('isub', 3, b), 8)), 24),
+    'options->lower_extract_byte'),
+
+   (('extract_u8', a, b),
+    ('iand', ('ushr', a, ('imul', b, 8)), 0xff),
+    'options->lower_extract_byte'),
+
+   (('extract_i16', a, b),
+    ('ishr', ('ishl', a, ('imul', ('isub', 1, b), 16)), 16),
+    'options->lower_extract_word'),
+
+   (('extract_u16', a, b),
+    ('iand', ('ushr', a, ('imul', b, 16)), 0xffff),
+    'options->lower_extract_word'),
 ]
 
 # Add optimizations to handle the case where the result of a ternary is