Emit basic HLX arithmetic, logical, min, max, and abs operations with gvec instead of helpers.
Signed-off-by: Marco Liebel <[email protected]> Signed-off-by: Brian Cain <[email protected]> --- target/hexagon/genptr.c | 1 + target/hexagon/hex_common.py | 149 +++++++++++++++++++++++++---------- 2 files changed, 107 insertions(+), 43 deletions(-) diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c index fd3f6a1edf..808caf4289 100644 --- a/target/hexagon/genptr.c +++ b/target/hexagon/genptr.c @@ -18,6 +18,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "cpu.h" +#include "hw/hexagon/hexagon_hlx.h" #include "internal.h" #include "tcg/tcg-op.h" #include "tcg/tcg-op-gvec.h" diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py index 091c1bf7ef..a6ac84d792 100755 --- a/target/hexagon/hex_common.py +++ b/target/hexagon/hex_common.py @@ -321,6 +321,63 @@ def skip_qemu_helper(tag): "LX_assign_w": {"op": "mov", "vece": "MO_64", "size": "2 * sizeof(HLXVector)"}, "LX_combine_w": {"op": "combine_pair", "vece": "MO_64"}, + "LX_add_h_sat": {"op": "gvec3_fn", "fn": "ssadd", + "vece": "MO_16"}, + "LX_add_uh_sat": {"op": "gvec3_fn", "fn": "usadd", + "vece": "MO_16"}, + "LX_sub_h_sat": {"op": "gvec3_fn", "fn": "sssub", + "vece": "MO_16"}, + "LX_sub_uh_sat": {"op": "gvec3_fn", "fn": "ussub", + "vece": "MO_16"}, + # Word forms use helpers because their halfwords are split. + "LX_add_hp_sat": {"op": "gvec3_fn", "fn": "ssadd", + "vece": "MO_16", "size": "2 * sizeof(HLXVector)"}, + "LX_add_uhp_sat":{"op": "gvec3_fn", "fn": "usadd", + "vece": "MO_16", "size": "2 * sizeof(HLXVector)"}, + "LX_sub_hp_sat": {"op": "gvec3_fn", "fn": "sssub", + "vece": "MO_16", "size": "2 * sizeof(HLXVector)"}, + "LX_sub_uhp_sat":{"op": "gvec3_fn", "fn": "ussub", + "vece": "MO_16", "size": "2 * sizeof(HLXVector)"}, + "LX_and": {"op": "gvec3_fn", "fn": "and", + "vece": "MO_64"}, + "LX_or": {"op": "gvec3_fn", "fn": "or", + "vece": "MO_64"}, + "LX_xor": {"op": "gvec3_fn", "fn": "xor", + "vece": "MO_64"}, + "LX_andn": {"op": "gvec3_fn", "fn": "andc", + "vece": "MO_64"}, + "LX_orn": {"op": "gvec3_fn", "fn": "orc", + "vece": "MO_64"}, + "LX_and_w": {"op": "gvec3_fn", "fn": "and", + "vece": "MO_64", "size": "2 * sizeof(HLXVector)"}, + "LX_or_w": {"op": "gvec3_fn", "fn": "or", + "vece": "MO_64", "size": "2 * sizeof(HLXVector)"}, + "LX_xor_w": {"op": "gvec3_fn", "fn": "xor", + "vece": "MO_64", "size": "2 * sizeof(HLXVector)"}, + "LX_andn_w": {"op": "gvec3_fn", "fn": "andc", + "vece": "MO_64", "size": "2 * sizeof(HLXVector)"}, + "LX_orn_w": {"op": "gvec3_fn", "fn": "orc", + "vece": "MO_64", "size": "2 * sizeof(HLXVector)"}, + "LX_min_h": {"op": "gvec3_fn", "fn": "smin", + "vece": "MO_16"}, + "LX_max_h": {"op": "gvec3_fn", "fn": "smax", + "vece": "MO_16"}, + "LX_min_uh": {"op": "gvec3_fn", "fn": "umin", + "vece": "MO_16"}, + "LX_max_uh": {"op": "gvec3_fn", "fn": "umax", + "vece": "MO_16"}, + "LX_min_hp": {"op": "gvec3_fn", "fn": "smin", + "vece": "MO_16", "size": "2 * sizeof(HLXVector)"}, + "LX_max_hp": {"op": "gvec3_fn", "fn": "smax", + "vece": "MO_16", "size": "2 * sizeof(HLXVector)"}, + "LX_min_uhp": {"op": "gvec3_fn", "fn": "umin", + "vece": "MO_16", "size": "2 * sizeof(HLXVector)"}, + "LX_max_uhp": {"op": "gvec3_fn", "fn": "umax", + "vece": "MO_16", "size": "2 * sizeof(HLXVector)"}, + "LX_abs_uh": {"op": "gvec2_fn", "fn": "abs", + "vece": "MO_16"}, + "LX_abs_uhp": {"op": "gvec2_fn", "fn": "abs", + "vece": "MO_16", "size": "2 * sizeof(HLXVector)"}, } def is_hlx_inline_tag(tag): @@ -449,27 +506,29 @@ def reg(i): {b}_base, {b}_off, {oprsz}, {maxsz}, &{table}); """)) - elif op == "gvec3_arr": - # Like gvec3, but table is a GVecGen3[4] indexed by vece. + elif op == "gvec3_fn": d, a, b = reg(0), reg(1), reg(2) - table = desc["table"] + fn = desc["fn"] if pair_dst: f.write(code_fmt(f"""\ - tcg_gen_gvec_3_var({d}_base, {d}_off, - {a}_base, {a}_off, - {b}_base, {b}_off, - {oprsz}, {maxsz}, &{table}[{vece}]); - tcg_gen_gvec_3_var({d}_base, {d}_off + sizeof(HLXVector), - {a}_base, {a}_off + sizeof(HLXVector), - {b}_base, {b}_off + sizeof(HLXVector), - {oprsz}, {maxsz}, &{table}[{vece}]); + tcg_gen_gvec_{fn}_var({vece}, + {d}_base, {d}_off, + {a}_base, {a}_off, + {b}_base, {b}_off, + {oprsz}, {maxsz}); + tcg_gen_gvec_{fn}_var({vece}, + {d}_base, {d}_off + sizeof(HLXVector), + {a}_base, {a}_off + sizeof(HLXVector), + {b}_base, {b}_off + sizeof(HLXVector), + {oprsz}, {maxsz}); """)) else: f.write(code_fmt(f"""\ - tcg_gen_gvec_3_var({d}_base, {d}_off, - {a}_base, {a}_off, - {b}_base, {b}_off, - {oprsz}, {maxsz}, &{table}[{vece}]); + tcg_gen_gvec_{fn}_var({vece}, + {d}_base, {d}_off, + {a}_base, {a}_off, + {b}_base, {b}_off, + {oprsz}, {maxsz}); """)) elif op == "combine_pair": dd, u, v = reg(0), reg(1), reg(2) @@ -486,7 +545,7 @@ def reg(i): {single}, {single}); """)) elif op == "gvec2": - # Two-operand op: dest and one source. table is a const GVecGen2. + # Two-operand op: dest and one source. table is a const GVecGen2. d, a = reg(0), reg(1) table = desc["table"] if pair_dst: @@ -504,46 +563,50 @@ def reg(i): {a}_base, {a}_off, {oprsz}, {maxsz}, &{table}); """)) - elif op == "gvec2_arr": - # Like gvec2, but table is a GVecGen2[4] indexed by vece. + elif op == "gvec2_fn": d, a = reg(0), reg(1) - table = desc["table"] + fn = desc["fn"] if pair_dst: f.write(code_fmt(f"""\ - tcg_gen_gvec_2_var({d}_base, {d}_off, - {a}_base, {a}_off, - {oprsz}, {maxsz}, &{table}[{vece}]); - tcg_gen_gvec_2_var({d}_base, {d}_off + sizeof(HLXVector), - {a}_base, {a}_off + sizeof(HLXVector), - {oprsz}, {maxsz}, &{table}[{vece}]); + tcg_gen_gvec_{fn}_var({vece}, + {d}_base, {d}_off, + {a}_base, {a}_off, + {oprsz}, {maxsz}); + tcg_gen_gvec_{fn}_var({vece}, + {d}_base, {d}_off + sizeof(HLXVector), + {a}_base, {a}_off + sizeof(HLXVector), + {oprsz}, {maxsz}); """)) else: f.write(code_fmt(f"""\ - tcg_gen_gvec_2_var({d}_base, {d}_off, - {a}_base, {a}_off, - {oprsz}, {maxsz}, &{table}[{vece}]); + tcg_gen_gvec_{fn}_var({vece}, + {d}_base, {d}_off, + {a}_base, {a}_off, + {oprsz}, {maxsz}); """)) - elif op == "cmp_gt": - # a > b is done as b < a, with the less-than descriptor in "table" + elif op == "cmp": d, a, b = reg(0), reg(1), reg(2) - table = desc["table"] + cond = desc["cond"] if pair_dst: f.write(code_fmt(f"""\ - tcg_gen_gvec_3_var({d}_base, {d}_off, - {b}_base, {b}_off, - {a}_base, {a}_off, - {oprsz}, {maxsz}, &{table}); - tcg_gen_gvec_3_var({d}_base, {d}_off + sizeof(HLXVector), - {b}_base, {b}_off + sizeof(HLXVector), - {a}_base, {a}_off + sizeof(HLXVector), - {oprsz}, {maxsz}, &{table}); + tcg_gen_gvec_cmp_var({cond}, {vece}, + {d}_base, {d}_off, + {a}_base, {a}_off, + {b}_base, {b}_off, + {oprsz}, {maxsz}); + tcg_gen_gvec_cmp_var({cond}, {vece}, + {d}_base, {d}_off + sizeof(HLXVector), + {a}_base, {a}_off + sizeof(HLXVector), + {b}_base, {b}_off + sizeof(HLXVector), + {oprsz}, {maxsz}); """)) else: f.write(code_fmt(f"""\ - tcg_gen_gvec_3_var({d}_base, {d}_off, - {b}_base, {b}_off, - {a}_base, {a}_off, - {oprsz}, {maxsz}, &{table}); + tcg_gen_gvec_cmp_var({cond}, {vece}, + {d}_base, {d}_off, + {a}_base, {a}_off, + {b}_base, {b}_off, + {oprsz}, {maxsz}); """)) elif op == "conv_h_to_w_pair": # lo = the source; hi = zeros (zxt) or the source >> 15 (sxt) -- 2.43.0
