Hexagon update

-----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEENjXHiM5iuR/UxZq0ewJE+xLeRCIFAmRwv6QACgkQewJE+xLe
 RCLRvQf/e0utA8/KAYwmay4dYiiVlrtJ4UVpwogQ8JC7je5H2+Gv633P4BF8uGAF
 HmhdUk031jvG/BvKGH+493ESKgtIX3caLxJInPtYu3elqKxZhqKpke2VPF3srrwI
 Mli8IqdwE2scSilG591xTjhU8vBGSm+hiQptSg9OaSotVcH8Qc/32+vudnr2JZtK
 ko3MqISMW/KvfD+x47UcX4IX4bmQfDyysQITQs9lfwYgzv/4drl6/7CUFQZ3b8Go
 Rz4ClbYhKT8YybJjX+yaKuTaHSrL9r0+90ORzYisEYcPiOOChmy9vv4HbZ1zTCbY
 MVJM69IPdZDi1quE00jULYEEPrHRoA==
 =vczK
 -----END PGP SIGNATURE-----

Merge tag 'pull-hex-20230526' of https://github.com/quic/qemu into staging

Hexagon update

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEENjXHiM5iuR/UxZq0ewJE+xLeRCIFAmRwv6QACgkQewJE+xLe
# RCLRvQf/e0utA8/KAYwmay4dYiiVlrtJ4UVpwogQ8JC7je5H2+Gv633P4BF8uGAF
# HmhdUk031jvG/BvKGH+493ESKgtIX3caLxJInPtYu3elqKxZhqKpke2VPF3srrwI
# Mli8IqdwE2scSilG591xTjhU8vBGSm+hiQptSg9OaSotVcH8Qc/32+vudnr2JZtK
# ko3MqISMW/KvfD+x47UcX4IX4bmQfDyysQITQs9lfwYgzv/4drl6/7CUFQZ3b8Go
# Rz4ClbYhKT8YybJjX+yaKuTaHSrL9r0+90ORzYisEYcPiOOChmy9vv4HbZ1zTCbY
# MVJM69IPdZDi1quE00jULYEEPrHRoA==
# =vczK
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 26 May 2023 07:18:12 AM PDT
# gpg:                using RSA key 3635C788CE62B91FD4C59AB47B0244FB12DE4422
# gpg: Good signature from "Taylor Simpson (Rock on) <tsimpson@quicinc.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 3635 C788 CE62 B91F D4C5  9AB4 7B02 44FB 12DE 4422

* tag 'pull-hex-20230526' of https://github.com/quic/qemu:
  Hexagon (target/hexagon) Change Hexagon maintainer
  Hexagon: fix outdated `hex_new_*` comments
  target/hexagon/*.py: clean up used 'toss' and 'numregs' vars
  Hexagon (target/hexagon) Fix assignment to tmp registers
  Hexagon (tests/tcg/hexagon) Clean up Hexagon check-tcg tests

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
master
Richard Henderson 2023-05-26 09:25:42 -07:00
commit 9c9fff18c4
32 changed files with 1149 additions and 1295 deletions

View File

@ -78,6 +78,7 @@ Philippe Mathieu-Daudé <philmd@linaro.org> <philmd@redhat.com>
Philippe Mathieu-Daudé <philmd@linaro.org> <philmd@fungible.com>
Stefan Brankovic <stefan.brankovic@syrmia.com> <stefan.brankovic@rt-rk.com.com>
Yongbok Kim <yongbok.kim@mips.com> <yongbok.kim@imgtec.com>
Taylor Simpson <ltaylorsimpson@gmail.com> <tsimpson@quicinc.com>
# Also list preferred name forms where people have changed their
# git author config, or had utf8/latin1 encoding issues.

View File

@ -218,7 +218,7 @@ F: tests/tcg/cris/
F: disas/cris.c
Hexagon TCG CPUs
M: Taylor Simpson <tsimpson@quicinc.com>
M: Brian Cain <bcain@quicinc.com>
S: Supported
F: target/hexagon/
X: target/hexagon/idef-parser/

View File

@ -165,7 +165,7 @@ def analyze_opn_new(f, tag, regtype, regid, regno):
hex_common.bad_register(regtype, regid)
def analyze_opn(f, tag, regtype, regid, toss, numregs, i):
def analyze_opn(f, tag, regtype, regid, i):
if hex_common.is_pair(regid):
analyze_opn_old(f, tag, regtype, regid, i)
elif hex_common.is_single(regid):
@ -174,9 +174,9 @@ def analyze_opn(f, tag, regtype, regid, toss, numregs, i):
elif hex_common.is_new_val(regtype, regid, tag):
analyze_opn_new(f, tag, regtype, regid, i)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
##
@ -202,8 +202,8 @@ def gen_analyze_func(f, tag, regs, imms):
i = 0
## Analyze all the registers
for regtype, regid, toss, numregs in regs:
analyze_opn(f, tag, regtype, regid, toss, numregs, i)
for regtype, regid in regs:
analyze_opn(f, tag, regtype, regid, i)
i += 1
has_generated_helper = not hex_common.skip_qemu_helper(

View File

@ -87,9 +87,9 @@ def gen_helper_arg_opn(f, regtype, regid, i, tag):
elif hex_common.is_new_val(regtype, regid, tag):
gen_helper_arg_new(f, regtype, regid, i)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
def gen_helper_arg_imm(f, immlett):
@ -135,7 +135,7 @@ def gen_helper_dest_decl_opn(f, regtype, regid, i):
else:
gen_helper_dest_decl(f, regtype, regid, i)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
def gen_helper_src_var_ext(f, regtype, regid):
@ -185,7 +185,7 @@ def gen_helper_return_opn(f, regtype, regid, i):
else:
gen_helper_return(f, regtype, regid, i)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
##
@ -208,7 +208,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
numresults = 0
numscalarresults = 0
numscalarreadwrite = 0
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
numresults += 1
if hex_common.is_scalar_reg(regtype):
@ -226,7 +226,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
## The return type of the function is the type of the destination
## register (if scalar)
i = 0
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
if hex_common.is_pair(regid):
if hex_common.is_hvx_reg(regtype):
@ -239,7 +239,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
else:
gen_helper_return_type(f, regtype, regid, i)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
i += 1
if numscalarresults == 0:
@ -248,7 +248,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
## Arguments include the vector destination operands
i = 1
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
if hex_common.is_pair(regid):
if hex_common.is_hvx_reg(regtype):
@ -262,12 +262,12 @@ def gen_helper_function(f, tag, tagregs, tagimms):
# This is the return value of the function
continue
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
i += 1
## For conditional instructions, we pass in the destination register
if "A_CONDEXEC" in hex_common.attribdict[tag]:
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
regtype
):
@ -275,7 +275,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
i += 1
## Arguments to the helper function are the source regs and immediates
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_read(regid):
if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid):
continue
@ -315,12 +315,12 @@ def gen_helper_function(f, tag, tagregs, tagimms):
## Declare the return variable
i = 0
if "A_CONDEXEC" not in hex_common.attribdict[tag]:
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_writeonly(regid):
gen_helper_dest_decl_opn(f, regtype, regid, i)
i += 1
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_read(regid):
if hex_common.is_pair(regid):
if hex_common.is_hvx_reg(regtype):
@ -329,7 +329,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
if hex_common.is_hvx_reg(regtype):
gen_helper_src_var_ext(f, regtype, regid)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
if hex_common.need_slot(tag):
if "A_LOAD" in hex_common.attribdict[tag]:
@ -345,7 +345,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
f.write(" arch_fpop_end(env);\n")
## Save/return the return variable
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
gen_helper_return_opn(f, regtype, regid, i)
f.write("}\n\n")

View File

@ -46,13 +46,13 @@ def_helper_types_pair = {
}
def gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i):
def gen_def_helper_opn(f, tag, regtype, regid, i):
if hex_common.is_pair(regid):
f.write(f", {def_helper_types_pair[regtype]}")
elif hex_common.is_single(regid):
f.write(f", {def_helper_types[regtype]}")
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
##
@ -68,7 +68,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
numresults = 0
numscalarresults = 0
numscalarreadwrite = 0
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
numresults += 1
if hex_common.is_scalar_reg(regtype):
@ -124,10 +124,10 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
## - Emit the scalar result
## - Emit the vector result
i = 0
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
if not hex_common.is_hvx_reg(regtype):
gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i)
gen_def_helper_opn(f, tag, regtype, regid, i)
i += 1
## Put the env between the outputs and inputs
@ -135,27 +135,27 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
i += 1
# Second pass
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
if hex_common.is_hvx_reg(regtype):
gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i)
gen_def_helper_opn(f, tag, regtype, regid, i)
i += 1
## For conditional instructions, we pass in the destination register
if "A_CONDEXEC" in hex_common.attribdict[tag]:
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
regtype
):
gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i)
gen_def_helper_opn(f, tag, regtype, regid, i)
i += 1
## Generate the qemu type for each input operand (regs and immediates)
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_read(regid):
if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid):
continue
gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i)
gen_def_helper_opn(f, tag, regtype, regid, i)
i += 1
for immlett, bits, immshift in imms:
f.write(", s32")

View File

@ -131,7 +131,7 @@ def main():
imms = tagimms[tag]
arguments = []
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
prefix = "in " if hex_common.is_read(regid) else ""
is_pair = hex_common.is_pair(regid)
@ -147,7 +147,7 @@ def main():
elif is_single_new:
arguments.append(f"{prefix}{regtype}{regid}N")
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
for immlett, bits, immshift in imms:
arguments.append(hex_common.imm_name(immlett))

View File

@ -70,7 +70,7 @@ def strip_reg_prefix(x):
def main():
hex_common.read_semantics_file(sys.argv[1])
hex_common.read_attribs_file(sys.argv[2])
tagregs = hex_common.get_tagregs()
tagregs = hex_common.get_tagregs(full=True)
tagimms = hex_common.get_tagimms()
with open(sys.argv[3], "w") as f:
@ -79,7 +79,7 @@ def main():
rregs = []
wregs = []
regids = ""
for regtype, regid, toss, numregs in regs:
for regtype, regid, _, numregs in regs:
if hex_common.is_read(regid):
if regid[0] not in regids:
regids += regid[0]

View File

@ -223,7 +223,7 @@ def genptr_decl_new(f, tag, regtype, regid, regno):
hex_common.bad_register(regtype, regid)
def genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i):
def genptr_decl_opn(f, tag, regtype, regid, i):
if hex_common.is_pair(regid):
genptr_decl(f, tag, regtype, regid, i)
elif hex_common.is_single(regid):
@ -232,9 +232,9 @@ def genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i):
elif hex_common.is_new_val(regtype, regid, tag):
genptr_decl_new(f, tag, regtype, regid, i)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
def genptr_decl_imm(f, immlett):
@ -354,12 +354,12 @@ def genptr_src_read_opn(f, regtype, regid, tag):
elif hex_common.is_new_val(regtype, regid, tag):
genptr_src_read_new(f, regtype, regid)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
def gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i):
def gen_helper_call_opn(f, tag, regtype, regid, i):
if i > 0:
f.write(", ")
if hex_common.is_pair(regid):
@ -370,9 +370,9 @@ def gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i):
elif hex_common.is_new_val(regtype, regid, tag):
f.write(f"{regtype}{regid}N")
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
def gen_helper_decl_imm(f, immlett):
@ -468,7 +468,7 @@ def genptr_dst_write_opn(f, regtype, regid, tag):
else:
genptr_dst_write(f, tag, regtype, regid)
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
##
@ -502,8 +502,8 @@ def gen_tcg_func(f, tag, regs, imms):
gen_decl_ea_tcg(f, tag)
i = 0
## Declare all the operands (regs and immediates)
for regtype, regid, toss, numregs in regs:
genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i)
for regtype, regid in regs:
genptr_decl_opn(f, tag, regtype, regid, i)
i += 1
for immlett, bits, immshift in imms:
genptr_decl_imm(f, immlett)
@ -514,14 +514,14 @@ def gen_tcg_func(f, tag, regs, imms):
f.write(" fCHECKFORGUEST();\n")
## Read all the inputs
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_read(regid):
genptr_src_read_opn(f, regtype, regid, tag)
if hex_common.is_idef_parser_enabled(tag):
declared = []
## Handle registers
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_pair(regid) or (
hex_common.is_single(regid)
and hex_common.is_old_val(regtype, regid, tag)
@ -532,7 +532,7 @@ def gen_tcg_func(f, tag, regs, imms):
elif hex_common.is_new_val(regtype, regid, tag):
declared.append(f"{regtype}{regid}N")
else:
hex_common.bad_register(regtype, regid, toss, numregs)
hex_common.bad_register(regtype, regid)
## Handle immediates
for immlett, bits, immshift in imms:
@ -564,11 +564,11 @@ def gen_tcg_func(f, tag, regs, imms):
f.write(f" gen_helper_{tag}(")
i = 0
## If there is a scalar result, it is the return type
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
if hex_common.is_hvx_reg(regtype):
continue
gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
gen_helper_call_opn(f, tag, regtype, regid, i)
i += 1
if i > 0:
f.write(", ")
@ -576,23 +576,23 @@ def gen_tcg_func(f, tag, regs, imms):
i = 1
## For conditional instructions, we pass in the destination register
if "A_CONDEXEC" in hex_common.attribdict[tag]:
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
regtype
):
gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
gen_helper_call_opn(f, tag, regtype, regid, i)
i += 1
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
if not hex_common.is_hvx_reg(regtype):
continue
gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
gen_helper_call_opn(f, tag, regtype, regid, i)
i += 1
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_read(regid):
if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid):
continue
gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i)
gen_helper_call_opn(f, tag, regtype, regid, i)
i += 1
for immlett, bits, immshift in imms:
gen_helper_call_imm(f, immlett)
@ -612,7 +612,7 @@ def gen_tcg_func(f, tag, regs, imms):
f.write(");\n")
## Write all the outputs
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if hex_common.is_written(regid):
genptr_dst_write_opn(f, regtype, regid, tag)

View File

@ -878,9 +878,9 @@ static void gen_endloop0(DisasContext *ctx)
*/
if (!ctx->is_tight_loop) {
/*
* if (hex_gpr[HEX_REG_LC0] > 1) {
* PC = hex_gpr[HEX_REG_SA0];
* hex_new_value[HEX_REG_LC0] = hex_gpr[HEX_REG_LC0] - 1;
* if (LC0 > 1) {
* PC = SA0;
* LC0--;
* }
*/
TCGLabel *label3 = gen_new_label();
@ -897,9 +897,9 @@ static void gen_endloop0(DisasContext *ctx)
static void gen_endloop1(DisasContext *ctx)
{
/*
* if (hex_gpr[HEX_REG_LC1] > 1) {
* PC = hex_gpr[HEX_REG_SA1];
* hex_new_value[HEX_REG_LC1] = hex_gpr[HEX_REG_LC1] - 1;
* if (LC1 > 1) {
* PC = SA1;
* LC1--;
* }
*/
TCGLabel *label = gen_new_label();
@ -946,14 +946,12 @@ static void gen_endloop01(DisasContext *ctx)
gen_set_label(label2);
/*
* if (hex_gpr[HEX_REG_LC0] > 1) {
* PC = hex_gpr[HEX_REG_SA0];
* hex_new_value[HEX_REG_LC0] = hex_gpr[HEX_REG_LC0] - 1;
* } else {
* if (hex_gpr[HEX_REG_LC1] > 1) {
* hex_next_pc = hex_gpr[HEX_REG_SA1];
* hex_new_value[HEX_REG_LC1] = hex_gpr[HEX_REG_LC1] - 1;
* }
* if (LC0 > 1) {
* PC = SA0;
* LC0--;
* } else if (LC1 > 1) {
* PC = SA1;
* LC1--;
* }
*/
tcg_gen_brcondi_tl(TCG_COND_LEU, hex_gpr[HEX_REG_LC0], 1, label3);

View File

@ -30,9 +30,8 @@ tags = [] # list of all tags
overrides = {} # tags with helper overrides
idef_parser_enabled = {} # tags enabled for idef-parser
def bad_register(*args):
args_str = ", ".join(map(str, args))
raise Exception(f"Bad register parse: {args_str}")
def bad_register(regtype, regid):
raise Exception(f"Bad register parse: regtype '{regtype}' regid '{regid}'")
# We should do this as a hash for performance,
# but to keep order let's keep it as a list.
@ -124,7 +123,7 @@ def calculate_attribs():
tagregs = get_tagregs()
for tag in tags:
regs = tagregs[tag]
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if regtype == "P" and is_written(regid):
attribdict[tag].add("A_WRITES_PRED_REG")
# Mark conditional jumps and calls
@ -170,10 +169,11 @@ def MACROATTRIB(macname, beh, attribstring):
attribs = []
macros[macname] = Macro(macname, beh, attribs)
def compute_tag_regs(tag):
return uniquify(regre.findall(behdict[tag]))
def compute_tag_regs(tag, full):
tagregs = regre.findall(behdict[tag])
if not full:
tagregs = map(lambda reg: reg[:2], tagregs)
return uniquify(tagregs)
def compute_tag_immediates(tag):
return uniquify(immre.findall(behdict[tag]))
@ -200,9 +200,9 @@ def compute_tag_immediates(tag):
## x, y read-write register
## xx, yy read-write register pair
##
def get_tagregs():
return dict(zip(tags, list(map(compute_tag_regs, tags))))
def get_tagregs(full=False):
compute_func = lambda tag: compute_tag_regs(tag, full)
return dict(zip(tags, list(map(compute_func, tags))))
def get_tagimms():
return dict(zip(tags, list(map(compute_tag_immediates, tags))))
@ -285,7 +285,7 @@ def need_pkt_need_commit(tag):
def need_condexec_reg(tag, regs):
if "A_CONDEXEC" in attribdict[tag]:
for regtype, regid, toss, numregs in regs:
for regtype, regid in regs:
if is_writeonly(regid) and not is_hvx_reg(regtype):
return True
return False

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -148,9 +148,9 @@ decode_shuffle_for_execution_vops(Packet *pkt)
int i;
for (i = 0; i < pkt->num_insns; i++) {
uint16_t opcode = pkt->insn[i].opcode;
if (GET_ATTRIB(opcode, A_LOAD) &&
(GET_ATTRIB(opcode, A_CVI_NEW) ||
GET_ATTRIB(opcode, A_CVI_TMP))) {
if ((GET_ATTRIB(opcode, A_LOAD) &&
GET_ATTRIB(opcode, A_CVI_NEW)) ||
GET_ATTRIB(opcode, A_CVI_TMP)) {
/*
* Find prior consuming vector instructions
* Move to end of packet

View File

@ -556,7 +556,7 @@ static void gen_start_packet(DisasContext *ctx)
}
/*
* Preload the predicated pred registers into hex_new_pred_value[pred_num]
* Preload the predicated pred registers into ctx->new_pred_value[pred_num]
* Only endloop instructions conditionally write to pred registers
*/
if (ctx->need_commit && pkt->pkt_has_endloop) {

View File

@ -91,8 +91,25 @@ HEX_TESTS += v73_scalar
TESTS += $(HEX_TESTS)
atomics: atomics.c hex_test.h
brev: brev.c hex_test.h
circ: circ.c hex_test.h
dual_stores: dual_stores.c hex_test.h
fpstuff: fpstuff.c hex_test.h
hex_sigsegv: hex_sigsegv.c hex_test.h
load_align: load_align.c hex_test.h
load_unpack: load_unpack.c hex_test.h
mem_noshuf_exception: mem_noshuf_exception.c hex_test.h
mem_noshuf: mem_noshuf.c hex_test.h
misc: misc.c hex_test.h
multi_result: multi_result.c hex_test.h
overflow: overflow.c hex_test.h
preg_alias: preg_alias.c hex_test.h
read_write_overlap: read_write_overlap.c hex_test.h
reg_mut: reg_mut.c hex_test.h
# This test has to be compiled for the -mv67t target
usr: usr.c
usr: usr.c hex_test.h
$(CC) $(CFLAGS) -mv67t -O2 -Wno-inline-asm -Wno-expansion-to-defined $< -o $@ $(LDFLAGS)
# Build this test with -mv71 to exercise the CABAC instruction

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -17,15 +17,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <pthread.h>
/* Using volatile because we are testing atomics */
static inline int atomic_inc32(volatile int *x)
int err;
#include "hex_test.h"
static inline int32_t atomic_inc32(int32_t *x)
{
int old, dummy;
int32_t old, dummy;
__asm__ __volatile__(
"1: %0 = memw_locked(%2)\n\t"
" %1 = add(%0, #1)\n\t"
@ -37,10 +41,9 @@ static inline int atomic_inc32(volatile int *x)
return old;
}
/* Using volatile because we are testing atomics */
static inline long long atomic_inc64(volatile long long *x)
static inline int64_t atomic_inc64(int64_t *x)
{
long long old, dummy;
int64_t old, dummy;
__asm__ __volatile__(
"1: %0 = memd_locked(%2)\n\t"
" %1 = #1\n\t"
@ -53,10 +56,9 @@ static inline long long atomic_inc64(volatile long long *x)
return old;
}
/* Using volatile because we are testing atomics */
static inline int atomic_dec32(volatile int *x)
static inline int32_t atomic_dec32(int32_t *x)
{
int old, dummy;
int32_t old, dummy;
__asm__ __volatile__(
"1: %0 = memw_locked(%2)\n\t"
" %1 = add(%0, #-1)\n\t"
@ -68,10 +70,9 @@ static inline int atomic_dec32(volatile int *x)
return old;
}
/* Using volatile because we are testing atomics */
static inline long long atomic_dec64(volatile long long *x)
static inline int64_t atomic_dec64(int64_t *x)
{
long long old, dummy;
int64_t old, dummy;
__asm__ __volatile__(
"1: %0 = memd_locked(%2)\n\t"
" %1 = #-1\n\t"
@ -85,17 +86,12 @@ static inline long long atomic_dec64(volatile long long *x)
}
#define LOOP_CNT 1000
/* Using volatile because we are testing atomics */
volatile int tick32 = 1;
/* Using volatile because we are testing atomics */
volatile long long tick64 = 1;
int err;
volatile int32_t tick32 = 1; /* Using volatile because we are testing atomics */
volatile int64_t tick64 = 1; /* Using volatile because we are testing atomics */
void *thread1_func(void *arg)
{
int i;
for (i = 0; i < LOOP_CNT; i++) {
for (int i = 0; i < LOOP_CNT; i++) {
atomic_inc32(&tick32);
atomic_dec64(&tick64);
}
@ -104,8 +100,7 @@ void *thread1_func(void *arg)
void *thread2_func(void *arg)
{
int i;
for (i = 0; i < LOOP_CNT; i++) {
for (int i = 0; i < LOOP_CNT; i++) {
atomic_dec32(&tick32);
atomic_inc64(&tick64);
}
@ -121,14 +116,8 @@ void test_pthread(void)
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
if (tick32 != 1) {
printf("ERROR: tick32 %d != 1\n", tick32);
err++;
}
if (tick64 != 1) {
printf("ERROR: tick64 %lld != 1\n", tick64);
err++;
}
check32(tick32, 1);
check64(tick64, 1);
}
int main(int argc, char **argv)

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -17,16 +17,19 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
int err;
#include "hex_test.h"
#define NBITS 8
#define SIZE (1 << NBITS)
long long dbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
int wbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
short hbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
unsigned char bbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
int64_t dbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
int32_t wbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
int16_t hbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
uint8_t bbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
/*
* We use the C preporcessor to deal with the combinations of types
@ -90,11 +93,10 @@ unsigned char bbuf[SIZE] __attribute__((aligned(1 << 16))) = {0};
#define BREV_STORE_wnew(ADDR, VAL, INC) \
BREV_STORE_NEW(w, ADDR, VAL, INC)
int bitreverse(int x)
uint32_t bitreverse(uint32_t x)
{
int result = 0;
int i;
for (i = 0; i < NBITS; i++) {
uint32_t result = 0;
for (int i = 0; i < NBITS; i++) {
result <<= 1;
result |= x & 1;
x >>= 1;
@ -102,26 +104,18 @@ int bitreverse(int x)
return result;
}
int sext8(int x)
int32_t sext8(int32_t x)
{
return (x << 24) >> 24;
}
void check(int i, long long result, long long expect)
{
if (result != expect) {
printf("ERROR(%d): 0x%04llx != 0x%04llx\n", i, result, expect);
err++;
}
}
#define TEST_BREV_LOAD(SZ, TYPE, BUF, SHIFT, EXP) \
do { \
p = BUF; \
for (i = 0; i < SIZE; i++) { \
for (int i = 0; i < SIZE; i++) { \
TYPE result; \
BREV_LOAD_##SZ(result, p, 1 << (SHIFT - NBITS)); \
check(i, result, EXP); \
check32(result, EXP); \
} \
} while (0)
@ -129,11 +123,11 @@ void check(int i, long long result, long long expect)
do { \
p = BUF; \
memset(BUF, 0xff, sizeof(BUF)); \
for (i = 0; i < SIZE; i++) { \
for (int i = 0; i < SIZE; i++) { \
BREV_STORE_##SZ(p, (TYPE)(VAL), 1 << (SHIFT - NBITS)); \
} \
for (i = 0; i < SIZE; i++) { \
check(i, BUF[i], bitreverse(i)); \
for (int i = 0; i < SIZE; i++) { \
check32(BUF[i], bitreverse(i)); \
} \
} while (0)
@ -141,11 +135,11 @@ void check(int i, long long result, long long expect)
do { \
p = BUF; \
memset(BUF, 0xff, sizeof(BUF)); \
for (i = 0; i < SIZE; i++) { \
for (int i = 0; i < SIZE; i++) { \
BREV_STORE_##SZ(p, i, 1 << (SHIFT - NBITS)); \
} \
for (i = 0; i < SIZE; i++) { \
check(i, BUF[i], bitreverse(i)); \
for (int i = 0; i < SIZE; i++) { \
check32(BUF[i], bitreverse(i)); \
} \
} while (0)
@ -158,9 +152,8 @@ int high_half[SIZE];
int main()
{
void *p;
int i;
for (i = 0; i < SIZE; i++) {
for (int i = 0; i < SIZE; i++) {
bbuf[i] = bitreverse(i);
hbuf[i] = bitreverse(i);
wbuf[i] = bitreverse(i);
@ -168,18 +161,18 @@ int main()
high_half[i] = i << 16;
}
TEST_BREV_LOAD(b, int, bbuf, 16, sext8(i));
TEST_BREV_LOAD(ub, int, bbuf, 16, i);
TEST_BREV_LOAD(h, int, hbuf, 15, i);
TEST_BREV_LOAD(uh, int, hbuf, 15, i);
TEST_BREV_LOAD(w, int, wbuf, 14, i);
TEST_BREV_LOAD(d, long long, dbuf, 13, i);
TEST_BREV_LOAD(b, int32_t, bbuf, 16, sext8(i));
TEST_BREV_LOAD(ub, int32_t, bbuf, 16, i);
TEST_BREV_LOAD(h, int32_t, hbuf, 15, i);
TEST_BREV_LOAD(uh, int32_t, hbuf, 15, i);
TEST_BREV_LOAD(w, int32_t, wbuf, 14, i);
TEST_BREV_LOAD(d, int64_t, dbuf, 13, i);
TEST_BREV_STORE(b, int, bbuf, i, 16);
TEST_BREV_STORE(h, int, hbuf, i, 15);
TEST_BREV_STORE(f, int, hbuf, high_half[i], 15);
TEST_BREV_STORE(w, int, wbuf, i, 14);
TEST_BREV_STORE(d, long long, dbuf, i, 13);
TEST_BREV_STORE(b, int32_t, bbuf, i, 16);
TEST_BREV_STORE(h, int32_t, hbuf, i, 15);
TEST_BREV_STORE(f, int32_t, hbuf, high_half[i], 15);
TEST_BREV_STORE(w, int32_t, wbuf, i, 14);
TEST_BREV_STORE(d, int64_t, dbuf, i, 13);
TEST_BREV_STORE_NEW(bnew, bbuf, 16);
TEST_BREV_STORE_NEW(hnew, hbuf, 15);

View File

@ -16,6 +16,11 @@
*/
#include <stdio.h>
#include <stdint.h>
int err;
#include "hex_test.h"
#define DEBUG 0
#define DEBUG_PRINTF(...) \
@ -31,10 +36,10 @@
#define NWORDS (NBYTES / sizeof(int))
#define NDOBLS (NBYTES / sizeof(long long))
long long dbuf[NDOBLS] __attribute__((aligned(1 << 12))) = {0};
int wbuf[NWORDS] __attribute__((aligned(1 << 12))) = {0};
short hbuf[NHALFS] __attribute__((aligned(1 << 12))) = {0};
unsigned char bbuf[NBYTES] __attribute__((aligned(1 << 12))) = {0};
int64_t dbuf[NDOBLS] __attribute__((aligned(1 << 12))) = {0};
int32_t wbuf[NWORDS] __attribute__((aligned(1 << 12))) = {0};
int16_t hbuf[NHALFS] __attribute__((aligned(1 << 12))) = {0};
uint8_t bbuf[NBYTES] __attribute__((aligned(1 << 12))) = {0};
/*
* We use the C preporcessor to deal with the combinations of types
@ -43,8 +48,7 @@ unsigned char bbuf[NBYTES] __attribute__((aligned(1 << 12))) = {0};
#define INIT(BUF, N) \
void init_##BUF(void) \
{ \
int i; \
for (i = 0; i < N; i++) { \
for (int i = 0; i < N; i++) { \
BUF[i] = i; \
} \
} \
@ -91,7 +95,7 @@ INIT(dbuf, NDOBLS)
* mreg[23:17] increment[6:0]
* mreg[16:0] circular buffer length
*/
static int build_mreg(int inc, int K, int len)
static int32_t build_mreg(int32_t inc, int32_t K, int32_t len)
{
return ((inc & 0x780) << 21) |
((K & 0xf) << 24) |
@ -213,31 +217,27 @@ static int build_mreg(int inc, int K, int len)
CIRC_STORE_NEW_REG(w, VAL, ADDR, START, LEN, INC)
int err;
/* We'll test increments +1 and -1 */
void check_load(int i, long long result, int inc, int size)
void __check_load(int line, int32_t i, int64_t res, int32_t inc, int32_t size)
{
int expect = (i * inc);
int32_t expect = (i * inc);
while (expect >= size) {
expect -= size;
}
while (expect < 0) {
expect += size;
}
if (result != expect) {
printf("ERROR(%d): %lld != %d\n", i, result, expect);
err++;
}
__check32(line, res, expect);
}
#define check_load(I, RES, INC, SZ) __check_load(__LINE__, I, RES, INC, SZ)
#define TEST_LOAD_IMM(SZ, TYPE, BUF, BUFSIZE, INC, FMT) \
void circ_test_load_imm_##SZ(void) \
{ \
TYPE *p = (TYPE *)BUF; \
int size = 10; \
int i; \
for (i = 0; i < BUFSIZE; i++) { \
int32_t size = 10; \
for (int i = 0; i < BUFSIZE; i++) { \
TYPE element; \
CIRC_LOAD_IMM_##SZ(element, p, BUF, size * sizeof(TYPE), (INC)); \
DEBUG_PRINTF("i = %2d, p = 0x%p, element = %2" #FMT "\n", \
@ -245,7 +245,7 @@ void circ_test_load_imm_##SZ(void) \
check_load(i, element, ((INC) / (int)sizeof(TYPE)), size); \
} \
p = (TYPE *)BUF; \
for (i = 0; i < BUFSIZE; i++) { \
for (int i = 0; i < BUFSIZE; i++) { \
TYPE element; \
CIRC_LOAD_IMM_##SZ(element, p, BUF, size * sizeof(TYPE), -(INC)); \
DEBUG_PRINTF("i = %2d, p = 0x%p, element = %2" #FMT "\n", \
@ -254,20 +254,19 @@ void circ_test_load_imm_##SZ(void) \
} \
}
TEST_LOAD_IMM(b, char, bbuf, NBYTES, 1, d)
TEST_LOAD_IMM(ub, unsigned char, bbuf, NBYTES, 1, d)
TEST_LOAD_IMM(h, short, hbuf, NHALFS, 2, d)
TEST_LOAD_IMM(uh, unsigned short, hbuf, NHALFS, 2, d)
TEST_LOAD_IMM(w, int, wbuf, NWORDS, 4, d)
TEST_LOAD_IMM(d, long long, dbuf, NDOBLS, 8, lld)
TEST_LOAD_IMM(b, int8_t, bbuf, NBYTES, 1, d)
TEST_LOAD_IMM(ub, uint8_t, bbuf, NBYTES, 1, d)
TEST_LOAD_IMM(h, int16_t, hbuf, NHALFS, 2, d)
TEST_LOAD_IMM(uh, uint16_t, hbuf, NHALFS, 2, d)
TEST_LOAD_IMM(w, int32_t, wbuf, NWORDS, 4, d)
TEST_LOAD_IMM(d, int64_t, dbuf, NDOBLS, 8, lld)
#define TEST_LOAD_REG(SZ, TYPE, BUF, BUFSIZE, FMT) \
void circ_test_load_reg_##SZ(void) \
{ \
TYPE *p = (TYPE *)BUF; \
int size = 13; \
int i; \
for (i = 0; i < BUFSIZE; i++) { \
int32_t size = 13; \
for (int i = 0; i < BUFSIZE; i++) { \
TYPE element; \
CIRC_LOAD_REG_##SZ(element, p, BUF, size * sizeof(TYPE), 1); \
DEBUG_PRINTF("i = %2d, p = 0x%p, element = %2" #FMT "\n", \
@ -275,7 +274,7 @@ void circ_test_load_reg_##SZ(void) \
check_load(i, element, 1, size); \
} \
p = (TYPE *)BUF; \
for (i = 0; i < BUFSIZE; i++) { \
for (int i = 0; i < BUFSIZE; i++) { \
TYPE element; \
CIRC_LOAD_REG_##SZ(element, p, BUF, size * sizeof(TYPE), -1); \
DEBUG_PRINTF("i = %2d, p = 0x%p, element = %2" #FMT "\n", \
@ -284,16 +283,16 @@ void circ_test_load_reg_##SZ(void) \
} \
}
TEST_LOAD_REG(b, char, bbuf, NBYTES, d)
TEST_LOAD_REG(ub, unsigned char, bbuf, NBYTES, d)
TEST_LOAD_REG(h, short, hbuf, NHALFS, d)
TEST_LOAD_REG(uh, unsigned short, hbuf, NHALFS, d)
TEST_LOAD_REG(w, int, wbuf, NWORDS, d)
TEST_LOAD_REG(d, long long, dbuf, NDOBLS, lld)
TEST_LOAD_REG(b, int8_t, bbuf, NBYTES, d)
TEST_LOAD_REG(ub, uint8_t, bbuf, NBYTES, d)
TEST_LOAD_REG(h, int16_t, hbuf, NHALFS, d)
TEST_LOAD_REG(uh, uint16_t, hbuf, NHALFS, d)
TEST_LOAD_REG(w, int32_t, wbuf, NWORDS, d)
TEST_LOAD_REG(d, int64_t, dbuf, NDOBLS, lld)
/* The circular stores will wrap around somewhere inside the buffer */
#define CIRC_VAL(SZ, TYPE, BUFSIZE) \
TYPE circ_val_##SZ(int i, int inc, int size) \
TYPE circ_val_##SZ(int i, int32_t inc, int32_t size) \
{ \
int mod = BUFSIZE % size; \
int elem = i * inc; \
@ -310,33 +309,25 @@ TYPE circ_val_##SZ(int i, int inc, int size) \
} \
}
CIRC_VAL(b, unsigned char, NBYTES)
CIRC_VAL(h, short, NHALFS)
CIRC_VAL(w, int, NWORDS)
CIRC_VAL(d, long long, NDOBLS)
CIRC_VAL(b, uint8_t, NBYTES)
CIRC_VAL(h, int16_t, NHALFS)
CIRC_VAL(w, int32_t, NWORDS)
CIRC_VAL(d, int64_t, NDOBLS)
/*
* Circular stores should only write to the first "size" elements of the buffer
* the remainder of the elements should have BUF[i] == i
*/
#define CHECK_STORE(SZ, BUF, BUFSIZE, FMT) \
void check_store_##SZ(int inc, int size) \
void check_store_##SZ(int32_t inc, int32_t size) \
{ \
int i; \
for (i = 0; i < size; i++) { \
for (int i = 0; i < size; i++) { \
DEBUG_PRINTF(#BUF "[%3d] = 0x%02" #FMT ", guess = 0x%02" #FMT "\n", \
i, BUF[i], circ_val_##SZ(i, inc, size)); \
if (BUF[i] != circ_val_##SZ(i, inc, size)) { \
printf("ERROR(%3d): 0x%02" #FMT " != 0x%02" #FMT "\n", \
i, BUF[i], circ_val_##SZ(i, inc, size)); \
err++; \
} \
check64(BUF[i], circ_val_##SZ(i, inc, size)); \
} \
for (i = size; i < BUFSIZE; i++) { \
if (BUF[i] != i) { \
printf("ERROR(%3d): 0x%02" #FMT " != 0x%02x\n", i, BUF[i], i); \
err++; \
} \
for (int i = size; i < BUFSIZE; i++) { \
check64(BUF[i], i); \
} \
}
@ -348,12 +339,11 @@ CHECK_STORE(d, dbuf, NDOBLS, llx)
#define CIRC_TEST_STORE_IMM(SZ, CHK, TYPE, BUF, BUFSIZE, SHIFT, INC) \
void circ_test_store_imm_##SZ(void) \
{ \
unsigned int size = 27; \
uint32_t size = 27; \
TYPE *p = BUF; \
TYPE val = 0; \
int i; \
init_##BUF(); \
for (i = 0; i < BUFSIZE; i++) { \
for (int i = 0; i < BUFSIZE; i++) { \
CIRC_STORE_IMM_##SZ(val << SHIFT, p, BUF, size * sizeof(TYPE), INC); \
val++; \
} \
@ -361,7 +351,7 @@ void circ_test_store_imm_##SZ(void) \
p = BUF; \
val = 0; \
init_##BUF(); \
for (i = 0; i < BUFSIZE; i++) { \
for (int i = 0; i < BUFSIZE; i++) { \
CIRC_STORE_IMM_##SZ(val << SHIFT, p, BUF, size * sizeof(TYPE), \
-(INC)); \
val++; \
@ -369,24 +359,23 @@ void circ_test_store_imm_##SZ(void) \
check_store_##CHK((-(INC) / (int)sizeof(TYPE)), size); \
}
CIRC_TEST_STORE_IMM(b, b, unsigned char, bbuf, NBYTES, 0, 1)
CIRC_TEST_STORE_IMM(h, h, short, hbuf, NHALFS, 0, 2)
CIRC_TEST_STORE_IMM(f, h, short, hbuf, NHALFS, 16, 2)
CIRC_TEST_STORE_IMM(w, w, int, wbuf, NWORDS, 0, 4)
CIRC_TEST_STORE_IMM(d, d, long long, dbuf, NDOBLS, 0, 8)
CIRC_TEST_STORE_IMM(bnew, b, unsigned char, bbuf, NBYTES, 0, 1)
CIRC_TEST_STORE_IMM(hnew, h, short, hbuf, NHALFS, 0, 2)
CIRC_TEST_STORE_IMM(wnew, w, int, wbuf, NWORDS, 0, 4)
CIRC_TEST_STORE_IMM(b, b, uint8_t, bbuf, NBYTES, 0, 1)
CIRC_TEST_STORE_IMM(h, h, int16_t, hbuf, NHALFS, 0, 2)
CIRC_TEST_STORE_IMM(f, h, int16_t, hbuf, NHALFS, 16, 2)
CIRC_TEST_STORE_IMM(w, w, int32_t, wbuf, NWORDS, 0, 4)
CIRC_TEST_STORE_IMM(d, d, int64_t, dbuf, NDOBLS, 0, 8)
CIRC_TEST_STORE_IMM(bnew, b, uint8_t, bbuf, NBYTES, 0, 1)
CIRC_TEST_STORE_IMM(hnew, h, int16_t, hbuf, NHALFS, 0, 2)
CIRC_TEST_STORE_IMM(wnew, w, int32_t, wbuf, NWORDS, 0, 4)
#define CIRC_TEST_STORE_REG(SZ, CHK, TYPE, BUF, BUFSIZE, SHIFT) \
void circ_test_store_reg_##SZ(void) \
{ \
TYPE *p = BUF; \
unsigned int size = 19; \
uint32_t size = 19; \
TYPE val = 0; \
int i; \
init_##BUF(); \
for (i = 0; i < BUFSIZE; i++) { \
for (int i = 0; i < BUFSIZE; i++) { \
CIRC_STORE_REG_##SZ(val << SHIFT, p, BUF, size * sizeof(TYPE), 1); \
val++; \
} \
@ -394,35 +383,34 @@ void circ_test_store_reg_##SZ(void) \
p = BUF; \
val = 0; \
init_##BUF(); \
for (i = 0; i < BUFSIZE; i++) { \
for (int i = 0; i < BUFSIZE; i++) { \
CIRC_STORE_REG_##SZ(val << SHIFT, p, BUF, size * sizeof(TYPE), -1); \
val++; \
} \
check_store_##CHK(-1, size); \
}
CIRC_TEST_STORE_REG(b, b, unsigned char, bbuf, NBYTES, 0)
CIRC_TEST_STORE_REG(h, h, short, hbuf, NHALFS, 0)
CIRC_TEST_STORE_REG(f, h, short, hbuf, NHALFS, 16)
CIRC_TEST_STORE_REG(w, w, int, wbuf, NWORDS, 0)
CIRC_TEST_STORE_REG(d, d, long long, dbuf, NDOBLS, 0)
CIRC_TEST_STORE_REG(bnew, b, unsigned char, bbuf, NBYTES, 0)
CIRC_TEST_STORE_REG(hnew, h, short, hbuf, NHALFS, 0)
CIRC_TEST_STORE_REG(wnew, w, int, wbuf, NWORDS, 0)
CIRC_TEST_STORE_REG(b, b, uint8_t, bbuf, NBYTES, 0)
CIRC_TEST_STORE_REG(h, h, int16_t, hbuf, NHALFS, 0)
CIRC_TEST_STORE_REG(f, h, int16_t, hbuf, NHALFS, 16)
CIRC_TEST_STORE_REG(w, w, int32_t, wbuf, NWORDS, 0)
CIRC_TEST_STORE_REG(d, d, int64_t, dbuf, NDOBLS, 0)
CIRC_TEST_STORE_REG(bnew, b, uint8_t, bbuf, NBYTES, 0)
CIRC_TEST_STORE_REG(hnew, h, int16_t, hbuf, NHALFS, 0)
CIRC_TEST_STORE_REG(wnew, w, int32_t, wbuf, NWORDS, 0)
/* Test the old scheme used in Hexagon V3 */
static void circ_test_v3(void)
{
int *p = wbuf;
int size = 15;
int32_t size = 15;
/* set high bit in K to test unsigned extract in fcirc */
int K = 8; /* 1024 bytes */
int element;
int i;
int32_t K = 8; /* 1024 bytes */
int32_t element;
init_wbuf();
for (i = 0; i < NWORDS; i++) {
for (int i = 0; i < NWORDS; i++) {
__asm__(
"r4 = %2\n\t"
"m1 = r4\n\t"

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,13 +16,18 @@
*/
#include <stdio.h>
#include <stdint.h>
int err;
#include "hex_test.h"
/*
* Make sure that two stores in the same packet honor proper
* semantics: slot 1 executes first, then slot 0.
* This is important when the addresses overlap.
*/
static inline void dual_stores(int *p, char *q, int x, char y)
static inline void dual_stores(int32_t *p, int8_t *q, int32_t x, int8_t y)
{
asm volatile("{\n\t"
" memw(%0) = %2\n\t"
@ -33,27 +38,17 @@ static inline void dual_stores(int *p, char *q, int x, char y)
}
typedef union {
int word;
char byte;
int32_t word;
int8_t byte;
} Dual;
int err;
static void check(Dual d, int expect)
{
if (d.word != expect) {
printf("ERROR: 0x%08x != 0x%08x\n", d.word, expect);
err++;
}
}
int main()
{
Dual d;
d.word = ~0;
dual_stores(&d.word, &d.byte, 0x12345678, 0xff);
check(d, 0x123456ff);
check32(d.word, 0x123456ff);
puts(err ? "FAIL" : "PASS");
return err;

View File

@ -20,91 +20,44 @@
*/
#include <stdio.h>
#include <stdint.h>
#include <float.h>
const int FPINVF_BIT = 1; /* Invalid */
const int FPINVF = 1 << FPINVF_BIT;
const int FPDBZF_BIT = 2; /* Divide by zero */
const int FPDBZF = 1 << FPDBZF_BIT;
const int FPOVFF_BIT = 3; /* Overflow */
const int FPOVFF = 1 << FPOVFF_BIT;
const int FPUNFF_BIT = 4; /* Underflow */
const int FPUNFF = 1 << FPUNFF_BIT;
const int FPINPF_BIT = 5; /* Inexact */
const int FPINPF = 1 << FPINPF_BIT;
const int SF_ZERO = 0x00000000;
const int SF_NaN = 0x7fc00000;
const int SF_NaN_special = 0x7f800001;
const int SF_ANY = 0x3f800000;
const int SF_HEX_NAN = 0xffffffff;
const int SF_small_neg = 0xab98fba8;
const int SF_denorm = 0x00000001;
const int SF_random = 0x346001d6;
const int SF_neg_zero = 0x80000000;
const long long DF_QNaN = 0x7ff8000000000000ULL;
const long long DF_SNaN = 0x7ff7000000000000ULL;
const long long DF_ANY = 0x3f80000000000000ULL;
const long long DF_HEX_NAN = 0xffffffffffffffffULL;
const long long DF_small_neg = 0xbd731f7500000000ULL;
int err;
#define CLEAR_FPSTATUS \
"r2 = usr\n\t" \
"r2 = clrbit(r2, #1)\n\t" \
"r2 = clrbit(r2, #2)\n\t" \
"r2 = clrbit(r2, #3)\n\t" \
"r2 = clrbit(r2, #4)\n\t" \
"r2 = clrbit(r2, #5)\n\t" \
"usr = r2\n\t"
#include "hex_test.h"
static void check_fpstatus_bit(int usr, int expect, int flag, const char *n)
static void check_fpstatus_bit(uint32_t usr, uint32_t expect, uint32_t flag,
const char *name)
{
int bit = 1 << flag;
uint32_t bit = 1 << flag;
if ((usr & bit) != (expect & bit)) {
printf("ERROR %s: usr = %d, expect = %d\n", n,
printf("ERROR %s: usr = %d, expect = %d\n", name,
(usr >> flag) & 1, (expect >> flag) & 1);
err++;
}
}
static void check_fpstatus(int usr, int expect)
static void check_fpstatus(uint32_t usr, uint32_t expect)
{
check_fpstatus_bit(usr, expect, FPINVF_BIT, "Invalid");
check_fpstatus_bit(usr, expect, FPDBZF_BIT, "Div by zero");
check_fpstatus_bit(usr, expect, FPOVFF_BIT, "Overflow");
check_fpstatus_bit(usr, expect, FPUNFF_BIT, "Underflow");
check_fpstatus_bit(usr, expect, FPINPF_BIT, "Inexact");
}
static void check32(int val, int expect)
{
if (val != expect) {
printf("ERROR: 0x%x != 0x%x\n", val, expect);
err++;
}
}
static void check64(unsigned long long val, unsigned long long expect)
{
if (val != expect) {
printf("ERROR: 0x%llx != 0x%llx\n", val, expect);
err++;
}
check_fpstatus_bit(usr, expect, USR_FPINVF_BIT, "Invalid");
check_fpstatus_bit(usr, expect, USR_FPDBZF_BIT, "Div by zero");
check_fpstatus_bit(usr, expect, USR_FPOVFF_BIT, "Overflow");
check_fpstatus_bit(usr, expect, USR_FPUNFF_BIT, "Underflow");
check_fpstatus_bit(usr, expect, USR_FPINPF_BIT, "Inexact");
}
static void check_compare_exception(void)
{
int cmp;
int usr;
uint32_t cmp;
uint32_t usr;
/* Check that FP compares are quiet (don't raise any execptions) */
asm (CLEAR_FPSTATUS
"p0 = sfcmp.eq(%2, %3)\n\t"
"%0 = p0\n\t"
"%1 = usr\n\t"
: "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "=r"(cmp), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "p0", "usr");
check32(cmp, 0);
check_fpstatus(usr, 0);
@ -113,7 +66,7 @@ static void check_compare_exception(void)
"p0 = sfcmp.gt(%2, %3)\n\t"
"%0 = p0\n\t"
"%1 = usr\n\t"
: "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "=r"(cmp), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "p0", "usr");
check32(cmp, 0);
check_fpstatus(usr, 0);
@ -122,7 +75,7 @@ static void check_compare_exception(void)
"p0 = sfcmp.ge(%2, %3)\n\t"
"%0 = p0\n\t"
"%1 = usr\n\t"
: "=r"(cmp), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "=r"(cmp), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "p0", "usr");
check32(cmp, 0);
check_fpstatus(usr, 0);
@ -131,7 +84,7 @@ static void check_compare_exception(void)
"p0 = dfcmp.eq(%2, %3)\n\t"
"%0 = p0\n\t"
"%1 = usr\n\t"
: "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY)
: "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
: "r2", "p0", "usr");
check32(cmp, 0);
check_fpstatus(usr, 0);
@ -140,7 +93,7 @@ static void check_compare_exception(void)
"p0 = dfcmp.gt(%2, %3)\n\t"
"%0 = p0\n\t"
"%1 = usr\n\t"
: "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY)
: "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
: "r2", "p0", "usr");
check32(cmp, 0);
check_fpstatus(usr, 0);
@ -149,7 +102,7 @@ static void check_compare_exception(void)
"p0 = dfcmp.ge(%2, %3)\n\t"
"%0 = p0\n\t"
"%1 = usr\n\t"
: "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY)
: "=r"(cmp), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
: "r2", "p0", "usr");
check32(cmp, 0);
check_fpstatus(usr, 0);
@ -157,8 +110,8 @@ static void check_compare_exception(void)
static void check_sfminmax(void)
{
int minmax;
int usr;
uint32_t minmax;
uint32_t usr;
/*
* Execute sfmin/sfmax instructions with one operand as NaN
@ -169,46 +122,46 @@ static void check_sfminmax(void)
asm (CLEAR_FPSTATUS
"%0 = sfmin(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "=r"(minmax), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr");
check64(minmax, SF_ANY);
check32(minmax, SF_any);
check_fpstatus(usr, 0);
asm (CLEAR_FPSTATUS
"%0 = sfmax(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "=r"(minmax), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr");
check64(minmax, SF_ANY);
check32(minmax, SF_any);
check_fpstatus(usr, 0);
/*
* Execute sfmin/sfmax instructions with both operands NaN
* Check that
* Result is SF_HEX_NAN
* Result is SF_HEX_NaN
* Invalid bit in USR is set
*/
asm (CLEAR_FPSTATUS
"%0 = sfmin(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_NaN)
: "=r"(minmax), "=r"(usr) : "r"(SF_QNaN), "r"(SF_QNaN)
: "r2", "usr");
check64(minmax, SF_HEX_NAN);
check32(minmax, SF_HEX_NaN);
check_fpstatus(usr, 0);
asm (CLEAR_FPSTATUS
"%0 = sfmax(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(SF_NaN), "r"(SF_NaN)
: "=r"(minmax), "=r"(usr) : "r"(SF_QNaN), "r"(SF_QNaN)
: "r2", "usr");
check64(minmax, SF_HEX_NAN);
check32(minmax, SF_HEX_NaN);
check_fpstatus(usr, 0);
}
static void check_dfminmax(void)
{
unsigned long long minmax;
int usr;
uint64_t minmax;
uint32_t usr;
/*
* Execute dfmin/dfmax instructions with one operand as SNaN
@ -219,18 +172,18 @@ static void check_dfminmax(void)
asm (CLEAR_FPSTATUS
"%0 = dfmin(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_ANY)
: "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_any)
: "r2", "usr");
check64(minmax, DF_ANY);
check_fpstatus(usr, FPINVF);
check64(minmax, DF_any);
check_fpstatus(usr, USR_FPINVF);
asm (CLEAR_FPSTATUS
"%0 = dfmax(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_ANY)
: "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_any)
: "r2", "usr");
check64(minmax, DF_ANY);
check_fpstatus(usr, FPINVF);
check64(minmax, DF_any);
check_fpstatus(usr, USR_FPINVF);
/*
* Execute dfmin/dfmax instructions with one operand as QNaN
@ -241,23 +194,23 @@ static void check_dfminmax(void)
asm (CLEAR_FPSTATUS
"%0 = dfmin(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY)
: "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
: "r2", "usr");
check64(minmax, DF_ANY);
check64(minmax, DF_any);
check_fpstatus(usr, 0);
asm (CLEAR_FPSTATUS
"%0 = dfmax(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY)
: "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
: "r2", "usr");
check64(minmax, DF_ANY);
check64(minmax, DF_any);
check_fpstatus(usr, 0);
/*
* Execute dfmin/dfmax instructions with both operands SNaN
* Check that
* Result is DF_HEX_NAN
* Result is DF_HEX_NaN
* Invalid bit in USR is set
*/
asm (CLEAR_FPSTATUS
@ -265,21 +218,21 @@ static void check_dfminmax(void)
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_SNaN)
: "r2", "usr");
check64(minmax, DF_HEX_NAN);
check_fpstatus(usr, FPINVF);
check64(minmax, DF_HEX_NaN);
check_fpstatus(usr, USR_FPINVF);
asm (CLEAR_FPSTATUS
"%0 = dfmax(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(DF_SNaN), "r"(DF_SNaN)
: "r2", "usr");
check64(minmax, DF_HEX_NAN);
check_fpstatus(usr, FPINVF);
check64(minmax, DF_HEX_NaN);
check_fpstatus(usr, USR_FPINVF);
/*
* Execute dfmin/dfmax instructions with both operands QNaN
* Check that
* Result is DF_HEX_NAN
* Result is DF_HEX_NaN
* No bit in USR is set
*/
asm (CLEAR_FPSTATUS
@ -287,7 +240,7 @@ static void check_dfminmax(void)
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_QNaN)
: "r2", "usr");
check64(minmax, DF_HEX_NAN);
check64(minmax, DF_HEX_NaN);
check_fpstatus(usr, 0);
asm (CLEAR_FPSTATUS
@ -295,15 +248,15 @@ static void check_dfminmax(void)
"%1 = usr\n\t"
: "=r"(minmax), "=r"(usr) : "r"(DF_QNaN), "r"(DF_QNaN)
: "r2", "usr");
check64(minmax, DF_HEX_NAN);
check64(minmax, DF_HEX_NaN);
check_fpstatus(usr, 0);
}
static void check_sfrecipa(void)
{
int result;
int usr;
int pred;
uint32_t result;
uint32_t usr;
uint32_t pred;
/*
* Check that sfrecipa doesn't set status bits when
@ -312,25 +265,25 @@ static void check_sfrecipa(void)
asm (CLEAR_FPSTATUS
"%0,p0 = sfrecipa(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "=r"(result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "p0", "usr");
check32(result, SF_HEX_NAN);
check32(result, SF_HEX_NaN);
check_fpstatus(usr, 0);
asm (CLEAR_FPSTATUS
"%0,p0 = sfrecipa(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(result), "=r"(usr) : "r"(SF_ANY), "r"(SF_NaN)
: "=r"(result), "=r"(usr) : "r"(SF_any), "r"(SF_QNaN)
: "r2", "p0", "usr");
check32(result, SF_HEX_NAN);
check32(result, SF_HEX_NaN);
check_fpstatus(usr, 0);
asm (CLEAR_FPSTATUS
"%0,p0 = sfrecipa(%2, %2)\n\t"
"%1 = usr\n\t"
: "=r"(result), "=r"(usr) : "r"(SF_NaN)
: "=r"(result), "=r"(usr) : "r"(SF_QNaN)
: "r2", "p0", "usr");
check32(result, SF_HEX_NAN);
check32(result, SF_HEX_NaN);
check_fpstatus(usr, 0);
/*
@ -340,26 +293,26 @@ static void check_sfrecipa(void)
asm (CLEAR_FPSTATUS
"%0,p0 = sfrecipa(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(result), "=r"(usr) : "r"(SF_NaN_special), "r"(SF_ANY)
: "=r"(result), "=r"(usr) : "r"(SF_QNaN_special), "r"(SF_any)
: "r2", "p0", "usr");
check32(result, SF_HEX_NAN);
check_fpstatus(usr, FPINVF);
check32(result, SF_HEX_NaN);
check_fpstatus(usr, USR_FPINVF);
asm (CLEAR_FPSTATUS
"%0,p0 = sfrecipa(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(result), "=r"(usr) : "r"(SF_ANY), "r"(SF_NaN_special)
: "=r"(result), "=r"(usr) : "r"(SF_any), "r"(SF_QNaN_special)
: "r2", "p0", "usr");
check32(result, SF_HEX_NAN);
check_fpstatus(usr, FPINVF);
check32(result, SF_HEX_NaN);
check_fpstatus(usr, USR_FPINVF);
asm (CLEAR_FPSTATUS
"%0,p0 = sfrecipa(%2, %2)\n\t"
"%1 = usr\n\t"
: "=r"(result), "=r"(usr) : "r"(SF_NaN_special)
: "=r"(result), "=r"(usr) : "r"(SF_QNaN_special)
: "r2", "p0", "usr");
check32(result, SF_HEX_NAN);
check_fpstatus(usr, FPINVF);
check32(result, SF_HEX_NaN);
check_fpstatus(usr, USR_FPINVF);
/*
* Check that sfrecipa properly sets divid-by-zero
@ -370,12 +323,12 @@ static void check_sfrecipa(void)
: "=r"(result), "=r"(usr) : "r"(0x885dc960), "r"(0x80000000)
: "r2", "p0", "usr");
check32(result, 0x3f800000);
check_fpstatus(usr, FPDBZF);
check_fpstatus(usr, USR_FPDBZF);
asm (CLEAR_FPSTATUS
"%0,p0 = sfrecipa(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(result), "=r"(usr) : "r"(0x7f800000), "r"(SF_ZERO)
: "=r"(result), "=r"(usr) : "r"(0x7f800000), "r"(SF_zero)
: "r2", "p0", "usr");
check32(result, 0x3f800000);
check_fpstatus(usr, 0);
@ -394,79 +347,79 @@ static void check_sfrecipa(void)
static void check_canonical_NaN(void)
{
int sf_result;
unsigned long long df_result;
int usr;
uint32_t sf_result;
uint64_t df_result;
uint32_t usr;
/* Check that each FP instruction properly returns SF_HEX_NAN/DF_HEX_NAN */
/* Check that each FP instruction properly returns SF_HEX_NaN/DF_HEX_NaN */
asm(CLEAR_FPSTATUS
"%0 = sfadd(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "=r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr");
check32(sf_result, SF_HEX_NAN);
check32(sf_result, SF_HEX_NaN);
check_fpstatus(usr, 0);
asm(CLEAR_FPSTATUS
"%0 = sfsub(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "=r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr");
check32(sf_result, SF_HEX_NAN);
check32(sf_result, SF_HEX_NaN);
check_fpstatus(usr, 0);
asm(CLEAR_FPSTATUS
"%0 = sfmpy(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "=r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr");
check32(sf_result, SF_HEX_NAN);
check32(sf_result, SF_HEX_NaN);
check_fpstatus(usr, 0);
sf_result = SF_ZERO;
sf_result = SF_zero;
asm(CLEAR_FPSTATUS
"%0 += sfmpy(%2, %3)\n\t"
"%1 = usr\n\t"
: "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr");
check32(sf_result, SF_HEX_NAN);
check32(sf_result, SF_HEX_NaN);
check_fpstatus(usr, 0);
sf_result = SF_ZERO;
sf_result = SF_zero;
asm(CLEAR_FPSTATUS
"p0 = !cmp.eq(r0, r0)\n\t"
"%0 += sfmpy(%2, %3, p0):scale\n\t"
"%1 = usr\n\t"
: "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr", "p0");
check32(sf_result, SF_HEX_NAN);
check32(sf_result, SF_HEX_NaN);
check_fpstatus(usr, 0);
sf_result = SF_ZERO;
sf_result = SF_zero;
asm(CLEAR_FPSTATUS
"%0 -= sfmpy(%2, %3)\n\t"
"%1 = usr\n\t"
: "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr");
check32(sf_result, SF_HEX_NAN);
check32(sf_result, SF_HEX_NaN);
check_fpstatus(usr, 0);
sf_result = SF_ZERO;
sf_result = SF_zero;
asm(CLEAR_FPSTATUS
"%0 += sfmpy(%2, %3):lib\n\t"
"%1 = usr\n\t"
: "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr");
check32(sf_result, SF_HEX_NAN);
check32(sf_result, SF_HEX_NaN);
check_fpstatus(usr, 0);
sf_result = SF_ZERO;
sf_result = SF_zero;
asm(CLEAR_FPSTATUS
"%0 -= sfmpy(%2, %3):lib\n\t"
"%1 = usr\n\t"
: "+r"(sf_result), "=r"(usr) : "r"(SF_NaN), "r"(SF_ANY)
: "+r"(sf_result), "=r"(usr) : "r"(SF_QNaN), "r"(SF_any)
: "r2", "usr");
check32(sf_result, SF_HEX_NAN);
check32(sf_result, SF_HEX_NaN);
check_fpstatus(usr, 0);
asm(CLEAR_FPSTATUS
@ -474,38 +427,38 @@ static void check_canonical_NaN(void)
"%1 = usr\n\t"
: "=r"(sf_result), "=r"(usr) : "r"(DF_QNaN)
: "r2", "usr");
check32(sf_result, SF_HEX_NAN);
check32(sf_result, SF_HEX_NaN);
check_fpstatus(usr, 0);
asm(CLEAR_FPSTATUS
"%0 = dfadd(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(df_result), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY)
: "=r"(df_result), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
: "r2", "usr");
check64(df_result, DF_HEX_NAN);
check64(df_result, DF_HEX_NaN);
check_fpstatus(usr, 0);
asm(CLEAR_FPSTATUS
"%0 = dfsub(%2, %3)\n\t"
"%1 = usr\n\t"
: "=r"(df_result), "=r"(usr) : "r"(DF_QNaN), "r"(DF_ANY)
: "=r"(df_result), "=r"(usr) : "r"(DF_QNaN), "r"(DF_any)
: "r2", "usr");
check64(df_result, DF_HEX_NAN);
check64(df_result, DF_HEX_NaN);
check_fpstatus(usr, 0);
asm(CLEAR_FPSTATUS
"%0 = convert_sf2df(%2)\n\t"
"%1 = usr\n\t"
: "=r"(df_result), "=r"(usr) : "r"(SF_NaN)
: "=r"(df_result), "=r"(usr) : "r"(SF_QNaN)
: "r2", "usr");
check64(df_result, DF_HEX_NAN);
check64(df_result, DF_HEX_NaN);
check_fpstatus(usr, 0);
}
static void check_invsqrta(void)
{
int result;
int predval;
uint32_t result;
uint32_t predval;
asm volatile("%0,p0 = sfinvsqrta(%2)\n\t"
"%1 = p0\n\t"
@ -518,7 +471,7 @@ static void check_invsqrta(void)
static void check_sffixupn(void)
{
int result;
uint32_t result;
/* Check that sffixupn properly deals with denorm */
asm volatile("%0 = sffixupn(%1, %2)\n\t"
@ -529,7 +482,7 @@ static void check_sffixupn(void)
static void check_sffixupd(void)
{
int result;
uint32_t result;
/* Check that sffixupd properly deals with denorm */
asm volatile("%0 = sffixupd(%1, %2)\n\t"
@ -540,36 +493,36 @@ static void check_sffixupd(void)
static void check_sffms(void)
{
int result;
uint32_t result;
/* Check that sffms properly deals with -0 */
result = SF_neg_zero;
result = SF_zero_neg;
asm ("%0 -= sfmpy(%1 , %2)\n\t"
: "+r"(result)
: "r"(SF_ZERO), "r"(SF_ZERO)
: "r"(SF_zero), "r"(SF_zero)
: "r12", "r8");
check32(result, SF_neg_zero);
check32(result, SF_zero_neg);
result = SF_ZERO;
result = SF_zero;
asm ("%0 -= sfmpy(%1 , %2)\n\t"
: "+r"(result)
: "r"(SF_neg_zero), "r"(SF_ZERO)
: "r"(SF_zero_neg), "r"(SF_zero)
: "r12", "r8");
check32(result, SF_ZERO);
check32(result, SF_zero);
result = SF_ZERO;
result = SF_zero;
asm ("%0 -= sfmpy(%1 , %2)\n\t"
: "+r"(result)
: "r"(SF_ZERO), "r"(SF_neg_zero)
: "r"(SF_zero), "r"(SF_zero_neg)
: "r12", "r8");
check32(result, SF_ZERO);
check32(result, SF_zero);
}
static void check_float2int_convs()
{
int res32;
long long res64;
int usr;
uint32_t res32;
uint64_t res64;
uint32_t usr;
/*
* Check that the various forms of float-to-unsigned
@ -581,7 +534,7 @@ static void check_float2int_convs()
: "=r"(res32), "=r"(usr) : "r"(SF_small_neg)
: "r2", "usr");
check32(res32, 0);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_sf2uw(%2):chop\n\t"
@ -589,7 +542,7 @@ static void check_float2int_convs()
: "=r"(res32), "=r"(usr) : "r"(SF_small_neg)
: "r2", "usr");
check32(res32, 0);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_sf2ud(%2)\n\t"
@ -597,7 +550,7 @@ static void check_float2int_convs()
: "=r"(res64), "=r"(usr) : "r"(SF_small_neg)
: "r2", "usr");
check64(res64, 0);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_sf2ud(%2):chop\n\t"
@ -605,7 +558,7 @@ static void check_float2int_convs()
: "=r"(res64), "=r"(usr) : "r"(SF_small_neg)
: "r2", "usr");
check64(res64, 0);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_df2uw(%2)\n\t"
@ -613,7 +566,7 @@ static void check_float2int_convs()
: "=r"(res32), "=r"(usr) : "r"(DF_small_neg)
: "r2", "usr");
check32(res32, 0);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_df2uw(%2):chop\n\t"
@ -621,7 +574,7 @@ static void check_float2int_convs()
: "=r"(res32), "=r"(usr) : "r"(DF_small_neg)
: "r2", "usr");
check32(res32, 0);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_df2ud(%2)\n\t"
@ -629,7 +582,7 @@ static void check_float2int_convs()
: "=r"(res64), "=r"(usr) : "r"(DF_small_neg)
: "r2", "usr");
check64(res64, 0);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_df2ud(%2):chop\n\t"
@ -637,7 +590,7 @@ static void check_float2int_convs()
: "=r"(res64), "=r"(usr) : "r"(DF_small_neg)
: "r2", "usr");
check64(res64, 0);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
/*
* Check that the various forms of float-to-signed return -1 for NaN
@ -645,34 +598,34 @@ static void check_float2int_convs()
asm(CLEAR_FPSTATUS
"%0 = convert_sf2w(%2)\n\t"
"%1 = usr\n\t"
: "=r"(res32), "=r"(usr) : "r"(SF_NaN)
: "=r"(res32), "=r"(usr) : "r"(SF_QNaN)
: "r2", "usr");
check32(res32, -1);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_sf2w(%2):chop\n\t"
"%1 = usr\n\t"
: "=r"(res32), "=r"(usr) : "r"(SF_NaN)
: "=r"(res32), "=r"(usr) : "r"(SF_QNaN)
: "r2", "usr");
check32(res32, -1);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_sf2d(%2)\n\t"
"%1 = usr\n\t"
: "=r"(res64), "=r"(usr) : "r"(SF_NaN)
: "=r"(res64), "=r"(usr) : "r"(SF_QNaN)
: "r2", "usr");
check64(res64, -1);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_sf2d(%2):chop\n\t"
"%1 = usr\n\t"
: "=r"(res64), "=r"(usr) : "r"(SF_NaN)
: "=r"(res64), "=r"(usr) : "r"(SF_QNaN)
: "r2", "usr");
check64(res64, -1);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_df2w(%2)\n\t"
@ -680,7 +633,7 @@ static void check_float2int_convs()
: "=r"(res32), "=r"(usr) : "r"(DF_QNaN)
: "r2", "usr");
check32(res32, -1);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_df2w(%2):chop\n\t"
@ -688,7 +641,7 @@ static void check_float2int_convs()
: "=r"(res32), "=r"(usr) : "r"(DF_QNaN)
: "r2", "usr");
check32(res32, -1);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_df2d(%2)\n\t"
@ -696,7 +649,7 @@ static void check_float2int_convs()
: "=r"(res64), "=r"(usr) : "r"(DF_QNaN)
: "r2", "usr");
check64(res64, -1);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
asm(CLEAR_FPSTATUS
"%0 = convert_df2d(%2):chop\n\t"
@ -704,13 +657,13 @@ static void check_float2int_convs()
: "=r"(res64), "=r"(usr) : "r"(DF_QNaN)
: "r2", "usr");
check64(res64, -1);
check_fpstatus(usr, FPINVF);
check_fpstatus(usr, USR_FPINVF);
}
static void check_float_consts(void)
{
int res32;
unsigned long long res64;
uint32_t res32;
uint64_t res64;
asm("%0 = sfmake(#%1):neg\n\t" : "=r"(res32) : "i"(0xf));
check32(res32, 0xbc9e0000);
@ -725,23 +678,23 @@ static void check_float_consts(void)
check64(res64, 0x3f93c00000000000ULL);
}
static inline unsigned long long dfmpyll(double x, double y)
static inline uint64_t dfmpyll(double x, double y)
{
unsigned long long res64;
uint64_t res64;
asm("%0 = dfmpyll(%1, %2)" : "=r"(res64) : "r"(x), "r"(y));
return res64;
}
static inline unsigned long long dfmpylh(double acc, double x, double y)
static inline uint64_t dfmpylh(double acc, double x, double y)
{
unsigned long long res64 = *(unsigned long long *)&acc;
uint64_t res64 = *(uint64_t *)&acc;
asm("%0 += dfmpylh(%1, %2)" : "+r"(res64) : "r"(x), "r"(y));
return res64;
}
static void check_dfmpyxx(void)
{
unsigned long long res64;
uint64_t res64;
res64 = dfmpyll(DBL_MIN, DBL_MIN);
check64(res64, 0ULL);

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2021-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -25,6 +25,8 @@
*/
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
@ -32,45 +34,23 @@
#include <setjmp.h>
#include <signal.h>
typedef unsigned char uint8_t;
int err;
int segv_caught;
#include "hex_test.h"
bool segv_caught;
#define SHOULD_NOT_CHANGE_VAL 5
int should_not_change = SHOULD_NOT_CHANGE_VAL;
int32_t should_not_change = SHOULD_NOT_CHANGE_VAL;
#define BUF_SIZE 300
unsigned char buf[BUF_SIZE];
static void __check(const char *filename, int line, int x, int expect)
{
if (x != expect) {
printf("ERROR %s:%d - %d != %d\n",
filename, line, x, expect);
err++;
}
}
#define check(x, expect) __check(__FILE__, __LINE__, (x), (expect))
static void __chk_error(const char *filename, int line, int ret)
{
if (ret < 0) {
printf("ERROR %s:%d - %d\n", filename, line, ret);
err++;
}
}
#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
uint8_t buf[BUF_SIZE];
jmp_buf jmp_env;
static void sig_segv(int sig, siginfo_t *info, void *puc)
{
check(sig, SIGSEGV);
segv_caught = 1;
check32(sig, SIGSEGV);
segv_caught = true;
longjmp(jmp_env, 1);
}
@ -98,8 +78,8 @@ int main()
act.sa_flags = 0;
chk_error(sigaction(SIGSEGV, &act, NULL));
check(segv_caught, 1);
check(should_not_change, SHOULD_NOT_CHANGE_VAL);
check32(segv_caught, true);
check32(should_not_change, SHOULD_NOT_CHANGE_VAL);
puts(err ? "FAIL" : "PASS");
return err ? EXIT_FAILURE : EXIT_SUCCESS;

View File

@ -0,0 +1,145 @@
/*
* Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HEX_TEST_H
#define HEX_TEST_H
static inline void __check32(int line, uint32_t val, uint32_t expect)
{
if (val != expect) {
printf("ERROR at line %d: 0x%08x != 0x%08x\n", line, val, expect);
err++;
}
}
#define check32(RES, EXP) __check32(__LINE__, RES, EXP)
static inline void __check64(int line, uint64_t val, uint64_t expect)
{
if (val != expect) {
printf("ERROR at line %d: 0x%016llx != 0x%016llx\n", line, val, expect);
err++;
}
}
#define check64(RES, EXP) __check64(__LINE__, RES, EXP)
static inline void __chk_error(const char *filename, int line, int ret)
{
if (ret < 0) {
printf("ERROR %s:%d - %d\n", filename, line, ret);
err++;
}
}
#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
static inline void __checkp(int line, void *p, void *expect)
{
if (p != expect) {
printf("ERROR at line %d: 0x%p != 0x%p\n", line, p, expect);
err++;
}
}
#define checkp(RES, EXP) __checkp(__LINE__, RES, EXP)
static inline void __check32_ne(int line, uint32_t val, uint32_t expect)
{
if (val == expect) {
printf("ERROR at line %d: 0x%08x == 0x%08x\n", line, val, expect);
err++;
}
}
#define check32_ne(RES, EXP) __check32_ne(__LINE__, RES, EXP)
static inline void __check64_ne(int line, uint64_t val, uint64_t expect)
{
if (val == expect) {
printf("ERROR at line %d: 0x%016llx == 0x%016llx\n", line, val, expect);
err++;
}
}
#define check64_ne(RES, EXP) __check64_ne(__LINE__, RES, EXP)
/* Define the bits in Hexagon USR register */
#define USR_OVF_BIT 0 /* Sticky saturation overflow */
#define USR_FPINVF_BIT 1 /* IEEE FP invalid sticky flag */
#define USR_FPDBZF_BIT 2 /* IEEE FP divide-by-zero sticky flag */
#define USR_FPOVFF_BIT 3 /* IEEE FP overflow sticky flag */
#define USR_FPUNFF_BIT 4 /* IEEE FP underflow sticky flag */
#define USR_FPINPF_BIT 5 /* IEEE FP inexact sticky flag */
/* Corresponding values in USR */
#define USR_CLEAR 0
#define USR_OVF (1 << USR_OVF_BIT)
#define USR_FPINVF (1 << USR_FPINVF_BIT)
#define USR_FPDBZF (1 << USR_FPDBZF_BIT)
#define USR_FPOVFF (1 << USR_FPOVFF_BIT)
#define USR_FPUNFF (1 << USR_FPUNFF_BIT)
#define USR_FPINPF (1 << USR_FPINPF_BIT)
/* Clear bits 0-5 in USR */
#define CLEAR_USRBITS \
"r2 = usr\n\t" \
"r2 = and(r2, #0xffffffc0)\n\t" \
"usr = r2\n\t"
/* Clear bits 1-5 in USR */
#define CLEAR_FPSTATUS \
"r2 = usr\n\t" \
"r2 = and(r2, #0xffffffc1)\n\t" \
"usr = r2\n\t"
/* Some useful floating point values */
const uint32_t SF_INF = 0x7f800000;
const uint32_t SF_QNaN = 0x7fc00000;
const uint32_t SF_QNaN_special = 0x7f800001;
const uint32_t SF_SNaN = 0x7fb00000;
const uint32_t SF_QNaN_neg = 0xffc00000;
const uint32_t SF_SNaN_neg = 0xffb00000;
const uint32_t SF_HEX_NaN = 0xffffffff;
const uint32_t SF_zero = 0x00000000;
const uint32_t SF_zero_neg = 0x80000000;
const uint32_t SF_one = 0x3f800000;
const uint32_t SF_one_recip = 0x3f7f0001; /* 0.9960... */
const uint32_t SF_one_invsqrta = 0x3f7f0000; /* 0.99609375 */
const uint32_t SF_two = 0x40000000;
const uint32_t SF_four = 0x40800000;
const uint32_t SF_small_neg = 0xab98fba8;
const uint32_t SF_large_pos = 0x5afa572e;
const uint32_t SF_any = 0x3f800000;
const uint32_t SF_denorm = 0x00000001;
const uint32_t SF_random = 0x346001d6;
const uint64_t DF_QNaN = 0x7ff8000000000000ULL;
const uint64_t DF_SNaN = 0x7ff7000000000000ULL;
const uint64_t DF_QNaN_neg = 0xfff8000000000000ULL;
const uint64_t DF_SNaN_neg = 0xfff7000000000000ULL;
const uint64_t DF_HEX_NaN = 0xffffffffffffffffULL;
const uint64_t DF_zero = 0x0000000000000000ULL;
const uint64_t DF_zero_neg = 0x8000000000000000ULL;
const uint64_t DF_any = 0x3f80000000000000ULL;
const uint64_t DF_one = 0x3ff0000000000000ULL;
const uint64_t DF_one_hh = 0x3ff001ff80000000ULL; /* 1.00048... */
const uint64_t DF_small_neg = 0xbd731f7500000000ULL;
const uint64_t DF_large_pos = 0x7f80000000000001ULL;
#endif

View File

@ -60,6 +60,36 @@ static void test_load_tmp(void)
check_output_w(__LINE__, BUFSIZE);
}
static void test_load_tmp2(void)
{
void *pout0 = &output[0];
void *pout1 = &output[1];
asm volatile(
"r0 = #0x03030303\n\t"
"v16 = vsplat(r0)\n\t"
"r0 = #0x04040404\n\t"
"v18 = vsplat(r0)\n\t"
"r0 = #0x05050505\n\t"
"v21 = vsplat(r0)\n\t"
"{\n\t"
" v25:24 += vmpyo(v18.w, v14.h)\n\t"
" v15:14.tmp = vcombine(v21, v16)\n\t"
"}\n\t"
"vmem(%0 + #0) = v24\n\t"
"vmem(%1 + #0) = v25\n\t"
: : "r"(pout0), "r"(pout1)
: "r0", "v16", "v18", "v21", "v24", "v25", "memory"
);
for (int i = 0; i < MAX_VEC_SIZE_BYTES / 4; ++i) {
expect[0].w[i] = 0x180c0000;
expect[1].w[i] = 0x000c1818;
}
check_output_w(__LINE__, 2);
}
static void test_load_cur(void)
{
void *p0 = buffer0;
@ -435,6 +465,7 @@ int main()
init_buffers();
test_load_tmp();
test_load_tmp2();
test_load_cur();
test_load_aligned();
test_load_unaligned();

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -29,41 +29,22 @@
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int err;
char buf[16] __attribute__((aligned(1 << 16)));
#include "hex_test.h"
int8_t buf[16] __attribute__((aligned(1 << 16)));
void init_buf(void)
{
int i;
for (i = 0; i < 16; i++) {
for (int i = 0; i < 16; i++) {
buf[i] = i + 1;
}
}
void __check(int line, long long result, long long expect)
{
if (result != expect) {
printf("ERROR at line %d: 0x%016llx != 0x%016llx\n",
line, result, expect);
err++;
}
}
#define check(RES, EXP) __check(__LINE__, RES, EXP)
void __checkp(int line, void *p, void *expect)
{
if (p != expect) {
printf("ERROR at line %d: 0x%p != 0x%p\n", line, p, expect);
err++;
}
}
#define checkp(RES, EXP) __checkp(__LINE__, RES, EXP)
/*
****************************************************************************
* _io addressing mode (addr + offset)
@ -81,15 +62,15 @@ void __checkp(int line, void *p, void *expect)
#define TEST_io(NAME, SZ, SIZE, EXP1, EXP2, EXP3, EXP4) \
void test_##NAME(void) \
{ \
long long result = ~0LL; \
int64_t result = ~0LL; \
LOAD_io_##SZ(result, buf, 0 * (SIZE)); \
check(result, (EXP1)); \
check64(result, (EXP1)); \
LOAD_io_##SZ(result, buf, 1 * (SIZE)); \
check(result, (EXP2)); \
check64(result, (EXP2)); \
LOAD_io_##SZ(result, buf, 2 * (SIZE)); \
check(result, (EXP3)); \
check64(result, (EXP3)); \
LOAD_io_##SZ(result, buf, 3 * (SIZE)); \
check(result, (EXP4)); \
check64(result, (EXP4)); \
}
TEST_io(loadalignb_io, b, 1,
@ -116,15 +97,15 @@ TEST_io(loadalignh_io, h, 2,
#define TEST_ur(NAME, SZ, SHIFT, RES1, RES2, RES3, RES4) \
void test_##NAME(void) \
{ \
long long result = ~0LL; \
uint64_t result = ~0LL; \
LOAD_ur_##SZ(result, (SHIFT), 0); \
check(result, (RES1)); \
check64(result, (RES1)); \
LOAD_ur_##SZ(result, (SHIFT), 1); \
check(result, (RES2)); \
check64(result, (RES2)); \
LOAD_ur_##SZ(result, (SHIFT), 2); \
check(result, (RES3)); \
check64(result, (RES3)); \
LOAD_ur_##SZ(result, (SHIFT), 3); \
check(result, (RES4)); \
check64(result, (RES4)); \
}
TEST_ur(loadalignb_ur, b, 1,
@ -150,19 +131,19 @@ TEST_ur(loadalignh_ur, h, 1,
#define TEST_ap(NAME, SZ, SIZE, RES1, RES2, RES3, RES4) \
void test_##NAME(void) \
{ \
long long result = ~0LL; \
int64_t result = ~0LL; \
void *ptr; \
LOAD_ap_##SZ(result, ptr, (buf + 0 * (SIZE))); \
check(result, (RES1)); \
check64(result, (RES1)); \
checkp(ptr, &buf[0 * (SIZE)]); \
LOAD_ap_##SZ(result, ptr, (buf + 1 * (SIZE))); \
check(result, (RES2)); \
check64(result, (RES2)); \
checkp(ptr, &buf[1 * (SIZE)]); \
LOAD_ap_##SZ(result, ptr, (buf + 2 * (SIZE))); \
check(result, (RES3)); \
check64(result, (RES3)); \
checkp(ptr, &buf[2 * (SIZE)]); \
LOAD_ap_##SZ(result, ptr, (buf + 3 * (SIZE))); \
check(result, (RES4)); \
check64(result, (RES4)); \
checkp(ptr, &buf[3 * (SIZE)]); \
}
@ -192,19 +173,19 @@ TEST_ap(loadalignh_ap, h, 2,
#define TEST_pr(NAME, SZ, SIZE, RES1, RES2, RES3, RES4) \
void test_##NAME(void) \
{ \
long long result = ~0LL; \
int64_t result = ~0LL; \
void *ptr = buf; \
LOAD_pr_##SZ(result, ptr, (SIZE)); \
check(result, (RES1)); \
check64(result, (RES1)); \
checkp(ptr, &buf[1 * (SIZE)]); \
LOAD_pr_##SZ(result, ptr, (SIZE)); \
check(result, (RES2)); \
check64(result, (RES2)); \
checkp(ptr, &buf[2 * (SIZE)]); \
LOAD_pr_##SZ(result, ptr, (SIZE)); \
check(result, (RES3)); \
check64(result, (RES3)); \
checkp(ptr, &buf[3 * (SIZE)]); \
LOAD_pr_##SZ(result, ptr, (SIZE)); \
check(result, (RES4)); \
check64(result, (RES4)); \
checkp(ptr, &buf[4 * (SIZE)]); \
}
@ -235,16 +216,16 @@ TEST_pr(loadalignh_pr, h, 2,
#define TEST_pbr(NAME, SZ, RES1, RES2, RES3, RES4) \
void test_##NAME(void) \
{ \
long long result = ~0LL; \
int64_t result = ~0LL; \
void *ptr = buf; \
LOAD_pbr_##SZ(result, ptr); \
check(result, (RES1)); \
check64(result, (RES1)); \
LOAD_pbr_##SZ(result, ptr); \
check(result, (RES2)); \
check64(result, (RES2)); \
LOAD_pbr_##SZ(result, ptr); \
check(result, (RES3)); \
check64(result, (RES3)); \
LOAD_pbr_##SZ(result, ptr); \
check(result, (RES4)); \
check64(result, (RES4)); \
}
TEST_pbr(loadalignb_pbr, b,
@ -270,19 +251,19 @@ TEST_pbr(loadalignh_pbr, h,
#define TEST_pi(NAME, SZ, INC, RES1, RES2, RES3, RES4) \
void test_##NAME(void) \
{ \
long long result = ~0LL; \
int64_t result = ~0LL; \
void *ptr = buf; \
LOAD_pi_##SZ(result, ptr, (INC)); \
check(result, (RES1)); \
check64(result, (RES1)); \
checkp(ptr, &buf[1 * (INC)]); \
LOAD_pi_##SZ(result, ptr, (INC)); \
check(result, (RES2)); \
check64(result, (RES2)); \
checkp(ptr, &buf[2 * (INC)]); \
LOAD_pi_##SZ(result, ptr, (INC)); \
check(result, (RES3)); \
check64(result, (RES3)); \
checkp(ptr, &buf[3 * (INC)]); \
LOAD_pi_##SZ(result, ptr, (INC)); \
check(result, (RES4)); \
check64(result, (RES4)); \
checkp(ptr, &buf[4 * (INC)]); \
}
@ -314,19 +295,19 @@ TEST_pi(loadalignh_pi, h, 2,
#define TEST_pci(NAME, SZ, LEN, INC, RES1, RES2, RES3, RES4) \
void test_##NAME(void) \
{ \
long long result = ~0LL; \
int64_t result = ~0LL; \
void *ptr = buf; \
LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
check(result, (RES1)); \
check64(result, (RES1)); \
checkp(ptr, &buf[(1 * (INC)) % (LEN)]); \
LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
check(result, (RES2)); \
check64(result, (RES2)); \
checkp(ptr, &buf[(2 * (INC)) % (LEN)]); \
LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
check(result, (RES3)); \
check64(result, (RES3)); \
checkp(ptr, &buf[(3 * (INC)) % (LEN)]); \
LOAD_pci_##SZ(result, ptr, buf, (LEN), (INC)); \
check(result, (RES4)); \
check64(result, (RES4)); \
checkp(ptr, &buf[(4 * (INC)) % (LEN)]); \
}
@ -359,19 +340,19 @@ TEST_pci(loadalignh_pci, h, 4, 2,
#define TEST_pcr(NAME, SZ, SIZE, LEN, INC, RES1, RES2, RES3, RES4) \
void test_##NAME(void) \
{ \
long long result = ~0LL; \
int64_t result = ~0LL; \
void *ptr = buf; \
LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
check(result, (RES1)); \
check64(result, (RES1)); \
checkp(ptr, &buf[(1 * (INC) * (SIZE)) % (LEN)]); \
LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
check(result, (RES2)); \
check64(result, (RES2)); \
checkp(ptr, &buf[(2 * (INC) * (SIZE)) % (LEN)]); \
LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
check(result, (RES3)); \
check64(result, (RES3)); \
checkp(ptr, &buf[(3 * (INC) * (SIZE)) % (LEN)]); \
LOAD_pcr_##SZ(result, ptr, buf, (LEN), (INC)); \
check(result, (RES4)); \
check64(result, (RES4)); \
checkp(ptr, &buf[(4 * (INC) * (SIZE)) % (LEN)]); \
}

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -31,42 +31,23 @@
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int err;
char buf[16] __attribute__((aligned(1 << 16)));
#include "hex_test.h"
int8_t buf[16] __attribute__((aligned(1 << 16)));
void init_buf(void)
{
int i;
for (i = 0; i < 16; i++) {
for (int i = 0; i < 16; i++) {
int sign = i % 2 == 0 ? 0x80 : 0;
buf[i] = sign | (i + 1);
}
}
void __check(int line, long long result, long long expect)
{
if (result != expect) {
printf("ERROR at line %d: 0x%08llx != 0x%08llx\n",
line, result, expect);
err++;
}
}
#define check(RES, EXP) __check(__LINE__, RES, EXP)
void __checkp(int line, void *p, void *expect)
{
if (p != expect) {
printf("ERROR at line %d: 0x%p != 0x%p\n", line, p, expect);
err++;
}
}
#define checkp(RES, EXP) __checkp(__LINE__, RES, EXP)
/*
****************************************************************************
* _io addressing mode (addr + offset)
@ -87,24 +68,24 @@ void test_##NAME(void) \
TYPE result; \
init_buf(); \
BxW_LOAD_io_##SIGN(result, buf, 0 * (SIZE)); \
check(result, (EXP1) | (EXT)); \
check64(result, (EXP1) | (EXT)); \
BxW_LOAD_io_##SIGN(result, buf, 1 * (SIZE)); \
check(result, (EXP2) | (EXT)); \
check64(result, (EXP2) | (EXT)); \
BxW_LOAD_io_##SIGN(result, buf, 2 * (SIZE)); \
check(result, (EXP3) | (EXT)); \
check64(result, (EXP3) | (EXT)); \
BxW_LOAD_io_##SIGN(result, buf, 3 * (SIZE)); \
check(result, (EXP4) | (EXT)); \
check64(result, (EXP4) | (EXT)); \
}
TEST_io(loadbzw2_io, int, Z, 2, 0x00000000,
TEST_io(loadbzw2_io, int32_t, Z, 2, 0x00000000,
0x00020081, 0x00040083, 0x00060085, 0x00080087)
TEST_io(loadbsw2_io, int, S, 2, 0x0000ff00,
TEST_io(loadbsw2_io, int32_t, S, 2, 0x0000ff00,
0x00020081, 0x00040083, 0x00060085, 0x00080087)
TEST_io(loadbzw4_io, long long, Z, 4, 0x0000000000000000LL,
TEST_io(loadbzw4_io, int64_t, Z, 4, 0x0000000000000000LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
TEST_io(loadbsw4_io, long long, S, 4, 0x0000ff000000ff00LL,
TEST_io(loadbsw4_io, int64_t, S, 4, 0x0000ff000000ff00LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
@ -128,23 +109,23 @@ void test_##NAME(void) \
TYPE result; \
init_buf(); \
BxW_LOAD_ur_##SIGN(result, (SHIFT), 0); \
check(result, (RES1) | (EXT)); \
check64(result, (RES1) | (EXT)); \
BxW_LOAD_ur_##SIGN(result, (SHIFT), 1); \
check(result, (RES2) | (EXT)); \
check64(result, (RES2) | (EXT)); \
BxW_LOAD_ur_##SIGN(result, (SHIFT), 2); \
check(result, (RES3) | (EXT)); \
check64(result, (RES3) | (EXT)); \
BxW_LOAD_ur_##SIGN(result, (SHIFT), 3); \
check(result, (RES4) | (EXT)); \
check64(result, (RES4) | (EXT)); \
} \
TEST_ur(loadbzw2_ur, int, Z, 1, 0x00000000,
TEST_ur(loadbzw2_ur, int32_t, Z, 1, 0x00000000,
0x00020081, 0x00040083, 0x00060085, 0x00080087)
TEST_ur(loadbsw2_ur, int, S, 1, 0x0000ff00,
TEST_ur(loadbsw2_ur, int32_t, S, 1, 0x0000ff00,
0x00020081, 0x00040083, 0x00060085, 0x00080087)
TEST_ur(loadbzw4_ur, long long, Z, 2, 0x0000000000000000LL,
TEST_ur(loadbzw4_ur, int64_t, Z, 2, 0x0000000000000000LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
TEST_ur(loadbsw4_ur, long long, S, 2, 0x0000ff000000ff00LL,
TEST_ur(loadbsw4_ur, int64_t, S, 2, 0x0000ff000000ff00LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
@ -168,27 +149,27 @@ void test_##NAME(void) \
void *ptr; \
init_buf(); \
BxW_LOAD_ap_##SIGN(result, ptr, (buf + 0 * (SIZE))); \
check(result, (RES1) | (EXT)); \
check64(result, (RES1) | (EXT)); \
checkp(ptr, &buf[0 * (SIZE)]); \
BxW_LOAD_ap_##SIGN(result, ptr, (buf + 1 * (SIZE))); \
check(result, (RES2) | (EXT)); \
check64(result, (RES2) | (EXT)); \
checkp(ptr, &buf[1 * (SIZE)]); \
BxW_LOAD_ap_##SIGN(result, ptr, (buf + 2 * (SIZE))); \
check(result, (RES3) | (EXT)); \
check64(result, (RES3) | (EXT)); \
checkp(ptr, &buf[2 * (SIZE)]); \
BxW_LOAD_ap_##SIGN(result, ptr, (buf + 3 * (SIZE))); \
check(result, (RES4) | (EXT)); \
check64(result, (RES4) | (EXT)); \
checkp(ptr, &buf[3 * (SIZE)]); \
}
TEST_ap(loadbzw2_ap, int, Z, 2, 0x00000000,
TEST_ap(loadbzw2_ap, int32_t, Z, 2, 0x00000000,
0x00020081, 0x00040083, 0x00060085, 0x00080087)
TEST_ap(loadbsw2_ap, int, S, 2, 0x0000ff00,
TEST_ap(loadbsw2_ap, int32_t, S, 2, 0x0000ff00,
0x00020081, 0x00040083, 0x00060085, 0x00080087)
TEST_ap(loadbzw4_ap, long long, Z, 4, 0x0000000000000000LL,
TEST_ap(loadbzw4_ap, int64_t, Z, 4, 0x0000000000000000LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
TEST_ap(loadbsw4_ap, long long, S, 4, 0x0000ff000000ff00LL,
TEST_ap(loadbsw4_ap, int64_t, S, 4, 0x0000ff000000ff00LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
@ -215,27 +196,27 @@ void test_##NAME(void) \
void *ptr = buf; \
init_buf(); \
BxW_LOAD_pr_##SIGN(result, ptr, (SIZE)); \
check(result, (RES1) | (EXT)); \
check64(result, (RES1) | (EXT)); \
checkp(ptr, &buf[1 * (SIZE)]); \
BxW_LOAD_pr_##SIGN(result, ptr, (SIZE)); \
check(result, (RES2) | (EXT)); \
check64(result, (RES2) | (EXT)); \
checkp(ptr, &buf[2 * (SIZE)]); \
BxW_LOAD_pr_##SIGN(result, ptr, (SIZE)); \
check(result, (RES3) | (EXT)); \
check64(result, (RES3) | (EXT)); \
checkp(ptr, &buf[3 * (SIZE)]); \
BxW_LOAD_pr_##SIGN(result, ptr, (SIZE)); \
check(result, (RES4) | (EXT)); \
check64(result, (RES4) | (EXT)); \
checkp(ptr, &buf[4 * (SIZE)]); \
}
TEST_pr(loadbzw2_pr, int, Z, 2, 0x00000000,
TEST_pr(loadbzw2_pr, int32_t, Z, 2, 0x00000000,
0x00020081, 0x0040083, 0x00060085, 0x00080087)
TEST_pr(loadbsw2_pr, int, S, 2, 0x0000ff00,
TEST_pr(loadbsw2_pr, int32_t, S, 2, 0x0000ff00,
0x00020081, 0x0040083, 0x00060085, 0x00080087)
TEST_pr(loadbzw4_pr, long long, Z, 4, 0x0000000000000000LL,
TEST_pr(loadbzw4_pr, int64_t, Z, 4, 0x0000000000000000LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
TEST_pr(loadbsw4_pr, long long, S, 4, 0x0000ff000000ff00LL,
TEST_pr(loadbsw4_pr, int64_t, S, 4, 0x0000ff000000ff00LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
@ -263,23 +244,23 @@ void test_##NAME(void) \
void *ptr = buf; \
init_buf(); \
BxW_LOAD_pbr_##SIGN(result, ptr); \
check(result, (RES1) | (EXT)); \
check64(result, (RES1) | (EXT)); \
BxW_LOAD_pbr_##SIGN(result, ptr); \
check(result, (RES2) | (EXT)); \
check64(result, (RES2) | (EXT)); \
BxW_LOAD_pbr_##SIGN(result, ptr); \
check(result, (RES3) | (EXT)); \
check64(result, (RES3) | (EXT)); \
BxW_LOAD_pbr_##SIGN(result, ptr); \
check(result, (RES4) | (EXT)); \
check64(result, (RES4) | (EXT)); \
}
TEST_pbr(loadbzw2_pbr, int, Z, 0x00000000,
TEST_pbr(loadbzw2_pbr, int32_t, Z, 0x00000000,
0x00020081, 0x000a0089, 0x00060085, 0x000e008d)
TEST_pbr(loadbsw2_pbr, int, S, 0x0000ff00,
TEST_pbr(loadbsw2_pbr, int32_t, S, 0x0000ff00,
0x00020081, 0x000aff89, 0x0006ff85, 0x000eff8d)
TEST_pbr(loadbzw4_pbr, long long, Z, 0x0000000000000000LL,
TEST_pbr(loadbzw4_pbr, int64_t, Z, 0x0000000000000000LL,
0x0004008300020081LL, 0x000c008b000a0089LL,
0x0008008700060085LL, 0x0010008f000e008dLL)
TEST_pbr(loadbsw4_pbr, long long, S, 0x0000ff000000ff00LL,
TEST_pbr(loadbsw4_pbr, int64_t, S, 0x0000ff000000ff00LL,
0x0004008300020081LL, 0x000cff8b000aff89LL,
0x0008ff870006ff85LL, 0x0010ff8f000eff8dLL)
@ -303,27 +284,27 @@ void test_##NAME(void) \
void *ptr = buf; \
init_buf(); \
BxW_LOAD_pi_##SIGN(result, ptr, (INC)); \
check(result, (RES1) | (EXT)); \
check64(result, (RES1) | (EXT)); \
checkp(ptr, &buf[1 * (INC)]); \
BxW_LOAD_pi_##SIGN(result, ptr, (INC)); \
check(result, (RES2) | (EXT)); \
check64(result, (RES2) | (EXT)); \
checkp(ptr, &buf[2 * (INC)]); \
BxW_LOAD_pi_##SIGN(result, ptr, (INC)); \
check(result, (RES3) | (EXT)); \
check64(result, (RES3) | (EXT)); \
checkp(ptr, &buf[3 * (INC)]); \
BxW_LOAD_pi_##SIGN(result, ptr, (INC)); \
check(result, (RES4) | (EXT)); \
check64(result, (RES4) | (EXT)); \
checkp(ptr, &buf[4 * (INC)]); \
}
TEST_pi(loadbzw2_pi, int, Z, 2, 0x00000000,
TEST_pi(loadbzw2_pi, int32_t, Z, 2, 0x00000000,
0x00020081, 0x00040083, 0x00060085, 0x00080087)
TEST_pi(loadbsw2_pi, int, S, 2, 0x0000ff00,
TEST_pi(loadbsw2_pi, int32_t, S, 2, 0x0000ff00,
0x00020081, 0x00040083, 0x00060085, 0x00080087)
TEST_pi(loadbzw4_pi, long long, Z, 4, 0x0000000000000000LL,
TEST_pi(loadbzw4_pi, int64_t, Z, 4, 0x0000000000000000LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
TEST_pi(loadbsw4_pi, long long, S, 4, 0x0000ff000000ff00LL,
TEST_pi(loadbsw4_pi, int64_t, S, 4, 0x0000ff000000ff00LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x000c008b000a0089LL, 0x0010008f000e008dLL)
@ -352,27 +333,27 @@ void test_##NAME(void) \
void *ptr = buf; \
init_buf(); \
BxW_LOAD_pci_##SIGN(result, ptr, buf, (LEN), (INC)); \
check(result, (RES1) | (EXT)); \
check64(result, (RES1) | (EXT)); \
checkp(ptr, &buf[(1 * (INC)) % (LEN)]); \
BxW_LOAD_pci_##SIGN(result, ptr, buf, (LEN), (INC)); \
check(result, (RES2) | (EXT)); \
check64(result, (RES2) | (EXT)); \
checkp(ptr, &buf[(2 * (INC)) % (LEN)]); \
BxW_LOAD_pci_##SIGN(result, ptr, buf, (LEN), (INC)); \
check(result, (RES3) | (EXT)); \
check64(result, (RES3) | (EXT)); \
checkp(ptr, &buf[(3 * (INC)) % (LEN)]); \
BxW_LOAD_pci_##SIGN(result, ptr, buf, (LEN), (INC)); \
check(result, (RES4) | (EXT)); \
check64(result, (RES4) | (EXT)); \
checkp(ptr, &buf[(4 * (INC)) % (LEN)]); \
}
TEST_pci(loadbzw2_pci, int, Z, 6, 2, 0x00000000,
TEST_pci(loadbzw2_pci, int32_t, Z, 6, 2, 0x00000000,
0x00020081, 0x00040083, 0x00060085, 0x00020081)
TEST_pci(loadbsw2_pci, int, S, 6, 2, 0x0000ff00,
TEST_pci(loadbsw2_pci, int32_t, S, 6, 2, 0x0000ff00,
0x00020081, 0x00040083, 0x00060085, 0x00020081)
TEST_pci(loadbzw4_pci, long long, Z, 8, 4, 0x0000000000000000LL,
TEST_pci(loadbzw4_pci, int64_t, Z, 8, 4, 0x0000000000000000LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x0004008300020081LL, 0x0008008700060085LL)
TEST_pci(loadbsw4_pci, long long, S, 8, 4, 0x0000ff000000ff00LL,
TEST_pci(loadbsw4_pci, int64_t, S, 8, 4, 0x0000ff000000ff00LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x0004008300020081LL, 0x0008008700060085LL)
@ -403,27 +384,27 @@ void test_##NAME(void) \
void *ptr = buf; \
init_buf(); \
BxW_LOAD_pcr_##SIGN(result, ptr, buf, (LEN), (INC)); \
check(result, (RES1) | (EXT)); \
check64(result, (RES1) | (EXT)); \
checkp(ptr, &buf[(1 * (INC) * (SIZE)) % (LEN)]); \
BxW_LOAD_pcr_##SIGN(result, ptr, buf, (LEN), (INC)); \
check(result, (RES2) | (EXT)); \
check64(result, (RES2) | (EXT)); \
checkp(ptr, &buf[(2 * (INC) * (SIZE)) % (LEN)]); \
BxW_LOAD_pcr_##SIGN(result, ptr, buf, (LEN), (INC)); \
check(result, (RES3) | (EXT)); \
check64(result, (RES3) | (EXT)); \
checkp(ptr, &buf[(3 * (INC) * (SIZE)) % (LEN)]); \
BxW_LOAD_pcr_##SIGN(result, ptr, buf, (LEN), (INC)); \
check(result, (RES4) | (EXT)); \
check64(result, (RES4) | (EXT)); \
checkp(ptr, &buf[(4 * (INC) * (SIZE)) % (LEN)]); \
}
TEST_pcr(loadbzw2_pcr, int, Z, 2, 8, 2, 0x00000000,
TEST_pcr(loadbzw2_pcr, int32_t, Z, 2, 8, 2, 0x00000000,
0x00020081, 0x00060085, 0x00020081, 0x00060085)
TEST_pcr(loadbsw2_pcr, int, S, 2, 8, 2, 0x0000ff00,
TEST_pcr(loadbsw2_pcr, int32_t, S, 2, 8, 2, 0x0000ff00,
0x00020081, 0x00060085, 0x00020081, 0x00060085)
TEST_pcr(loadbzw4_pcr, long long, Z, 4, 8, 1, 0x0000000000000000LL,
TEST_pcr(loadbzw4_pcr, int64_t, Z, 4, 8, 1, 0x0000000000000000LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x0004008300020081LL, 0x0008008700060085LL)
TEST_pcr(loadbsw4_pcr, long long, S, 4, 8, 1, 0x0000ff000000ff00LL,
TEST_pcr(loadbsw4_pcr, int64_t, S, 4, 8, 1, 0x0000ff000000ff00LL,
0x0004008300020081LL, 0x0008008700060085LL,
0x0004008300020081LL, 0x0008008700060085LL)

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,6 +16,12 @@
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
int err;
#include "hex_test.h"
/*
* Make sure that the :mem_noshuf packet attribute is honored.
@ -25,9 +31,9 @@
*/
#define MEM_NOSHUF32(NAME, ST_TYPE, LD_TYPE, ST_OP, LD_OP) \
static inline unsigned int NAME(ST_TYPE * p, LD_TYPE * q, ST_TYPE x) \
static inline uint32_t NAME(ST_TYPE * p, LD_TYPE * q, ST_TYPE x) \
{ \
unsigned int ret; \
uint32_t ret; \
asm volatile("{\n\t" \
" " #ST_OP "(%1) = %3\n\t" \
" %0 = " #LD_OP "(%2)\n\t" \
@ -39,9 +45,9 @@ static inline unsigned int NAME(ST_TYPE * p, LD_TYPE * q, ST_TYPE x) \
}
#define MEM_NOSHUF64(NAME, ST_TYPE, LD_TYPE, ST_OP, LD_OP) \
static inline unsigned long long NAME(ST_TYPE * p, LD_TYPE * q, ST_TYPE x) \
static inline uint64_t NAME(ST_TYPE * p, LD_TYPE * q, ST_TYPE x) \
{ \
unsigned long long ret; \
uint64_t ret; \
asm volatile("{\n\t" \
" " #ST_OP "(%1) = %3\n\t" \
" %0 = " #LD_OP "(%2)\n\t" \
@ -53,38 +59,39 @@ static inline unsigned long long NAME(ST_TYPE * p, LD_TYPE * q, ST_TYPE x) \
}
/* Store byte combinations */
MEM_NOSHUF32(mem_noshuf_sb_lb, signed char, signed char, memb, memb)
MEM_NOSHUF32(mem_noshuf_sb_lub, signed char, unsigned char, memb, memub)
MEM_NOSHUF32(mem_noshuf_sb_lh, signed char, signed short, memb, memh)
MEM_NOSHUF32(mem_noshuf_sb_luh, signed char, unsigned short, memb, memuh)
MEM_NOSHUF32(mem_noshuf_sb_lw, signed char, signed int, memb, memw)
MEM_NOSHUF64(mem_noshuf_sb_ld, signed char, signed long long, memb, memd)
MEM_NOSHUF32(mem_noshuf_sb_lb, int8_t, int8_t, memb, memb)
MEM_NOSHUF32(mem_noshuf_sb_lub, int8_t, uint8_t, memb, memub)
MEM_NOSHUF32(mem_noshuf_sb_lh, int8_t, int16_t, memb, memh)
MEM_NOSHUF32(mem_noshuf_sb_luh, int8_t, uint16_t, memb, memuh)
MEM_NOSHUF32(mem_noshuf_sb_lw, int8_t, int32_t, memb, memw)
MEM_NOSHUF64(mem_noshuf_sb_ld, int8_t, int64_t, memb, memd)
/* Store half combinations */
MEM_NOSHUF32(mem_noshuf_sh_lb, signed short, signed char, memh, memb)
MEM_NOSHUF32(mem_noshuf_sh_lub, signed short, unsigned char, memh, memub)
MEM_NOSHUF32(mem_noshuf_sh_lh, signed short, signed short, memh, memh)
MEM_NOSHUF32(mem_noshuf_sh_luh, signed short, unsigned short, memh, memuh)
MEM_NOSHUF32(mem_noshuf_sh_lw, signed short, signed int, memh, memw)
MEM_NOSHUF64(mem_noshuf_sh_ld, signed short, signed long long, memh, memd)
MEM_NOSHUF32(mem_noshuf_sh_lb, int16_t, int8_t, memh, memb)
MEM_NOSHUF32(mem_noshuf_sh_lub, int16_t, uint8_t, memh, memub)
MEM_NOSHUF32(mem_noshuf_sh_lh, int16_t, int16_t, memh, memh)
MEM_NOSHUF32(mem_noshuf_sh_luh, int16_t, uint16_t, memh, memuh)
MEM_NOSHUF32(mem_noshuf_sh_lw, int16_t, int32_t, memh, memw)
MEM_NOSHUF64(mem_noshuf_sh_ld, int16_t, int64_t, memh, memd)
/* Store word combinations */
MEM_NOSHUF32(mem_noshuf_sw_lb, signed int, signed char, memw, memb)
MEM_NOSHUF32(mem_noshuf_sw_lub, signed int, unsigned char, memw, memub)
MEM_NOSHUF32(mem_noshuf_sw_lh, signed int, signed short, memw, memh)
MEM_NOSHUF32(mem_noshuf_sw_luh, signed int, unsigned short, memw, memuh)
MEM_NOSHUF32(mem_noshuf_sw_lw, signed int, signed int, memw, memw)
MEM_NOSHUF64(mem_noshuf_sw_ld, signed int, signed long long, memw, memd)
MEM_NOSHUF32(mem_noshuf_sw_lb, int32_t, int8_t, memw, memb)
MEM_NOSHUF32(mem_noshuf_sw_lub, int32_t, uint8_t, memw, memub)
MEM_NOSHUF32(mem_noshuf_sw_lh, int32_t, int16_t, memw, memh)
MEM_NOSHUF32(mem_noshuf_sw_luh, int32_t, uint16_t, memw, memuh)
MEM_NOSHUF32(mem_noshuf_sw_lw, int32_t, int32_t, memw, memw)
MEM_NOSHUF64(mem_noshuf_sw_ld, int32_t, int64_t, memw, memd)
/* Store double combinations */
MEM_NOSHUF32(mem_noshuf_sd_lb, long long, signed char, memd, memb)
MEM_NOSHUF32(mem_noshuf_sd_lub, long long, unsigned char, memd, memub)
MEM_NOSHUF32(mem_noshuf_sd_lh, long long, signed short, memd, memh)
MEM_NOSHUF32(mem_noshuf_sd_luh, long long, unsigned short, memd, memuh)
MEM_NOSHUF32(mem_noshuf_sd_lw, long long, signed int, memd, memw)
MEM_NOSHUF64(mem_noshuf_sd_ld, long long, signed long long, memd, memd)
MEM_NOSHUF32(mem_noshuf_sd_lb, int64_t, int8_t, memd, memb)
MEM_NOSHUF32(mem_noshuf_sd_lub, int64_t, uint8_t, memd, memub)
MEM_NOSHUF32(mem_noshuf_sd_lh, int64_t, int16_t, memd, memh)
MEM_NOSHUF32(mem_noshuf_sd_luh, int64_t, uint16_t, memd, memuh)
MEM_NOSHUF32(mem_noshuf_sd_lw, int64_t, int32_t, memd, memw)
MEM_NOSHUF64(mem_noshuf_sd_ld, int64_t, int64_t, memd, memd)
static inline int pred_lw_sw(int pred, int *p, int *q, int x, int y)
static inline int pred_lw_sw(bool pred, int32_t *p, int32_t *q,
int32_t x, int32_t y)
{
int ret;
asm volatile("p0 = cmp.eq(%5, #0)\n\t"
@ -99,7 +106,8 @@ static inline int pred_lw_sw(int pred, int *p, int *q, int x, int y)
return ret;
}
static inline int pred_lw_sw_pi(int pred, int *p, int *q, int x, int y)
static inline int pred_lw_sw_pi(bool pred, int32_t *p, int32_t *q,
int32_t x, int32_t y)
{
int ret;
asm volatile("p0 = cmp.eq(%5, #0)\n\t"
@ -115,10 +123,10 @@ static inline int pred_lw_sw_pi(int pred, int *p, int *q, int x, int y)
return ret;
}
static inline long long pred_ld_sd(int pred, long long *p, long long *q,
long long x, long long y)
static inline int64_t pred_ld_sd(bool pred, int64_t *p, int64_t *q,
int64_t x, int64_t y)
{
unsigned long long ret;
int64_t ret;
asm volatile("p0 = cmp.eq(%5, #0)\n\t"
"%0 = %3\n\t"
"{\n\t"
@ -131,10 +139,10 @@ static inline long long pred_ld_sd(int pred, long long *p, long long *q,
return ret;
}
static inline long long pred_ld_sd_pi(int pred, long long *p, long long *q,
long long x, long long y)
static inline int64_t pred_ld_sd_pi(bool pred, int64_t *p, int64_t *q,
int64_t x, int64_t y)
{
long long ret;
int64_t ret;
asm volatile("p0 = cmp.eq(%5, #0)\n\t"
"%0 = %3\n\t"
"r7 = %2\n\t"
@ -148,9 +156,9 @@ static inline long long pred_ld_sd_pi(int pred, long long *p, long long *q,
return ret;
}
static inline unsigned int cancel_sw_lb(int pred, int *p, signed char *q, int x)
static inline int32_t cancel_sw_lb(bool pred, int32_t *p, int8_t *q, int32_t x)
{
unsigned int ret;
int32_t ret;
asm volatile("p0 = cmp.eq(%4, #0)\n\t"
"{\n\t"
" if (!p0) memw(%1) = %3\n\t"
@ -162,10 +170,9 @@ static inline unsigned int cancel_sw_lb(int pred, int *p, signed char *q, int x)
return ret;
}
static inline
unsigned long long cancel_sw_ld(int pred, int *p, long long *q, int x)
static inline int64_t cancel_sw_ld(bool pred, int32_t *p, int64_t *q, int32_t x)
{
long long ret;
int64_t ret;
asm volatile("p0 = cmp.eq(%4, #0)\n\t"
"{\n\t"
" if (!p0) memw(%1) = %3\n\t"
@ -178,43 +185,21 @@ unsigned long long cancel_sw_ld(int pred, int *p, long long *q, int x)
}
typedef union {
signed long long d[2];
unsigned long long ud[2];
signed int w[4];
unsigned int uw[4];
signed short h[8];
unsigned short uh[8];
signed char b[16];
unsigned char ub[16];
int64_t d[2];
uint64_t ud[2];
int32_t w[4];
uint32_t uw[4];
int16_t h[8];
uint16_t uh[8];
int8_t b[16];
uint8_t ub[16];
} Memory;
int err;
#define check32(n, expect) check32_(n, expect, __LINE__)
static void check32_(int n, int expect, int line)
{
if (n != expect) {
printf("ERROR: 0x%08x != 0x%08x, line %d\n", n, expect, line);
err++;
}
}
#define check64(n, expect) check64_(n, expect, __LINE__)
static void check64_(long long n, long long expect, int line)
{
if (n != expect) {
printf("ERROR: 0x%08llx != 0x%08llx, line %d\n", n, expect, line);
err++;
}
}
int main()
{
Memory n;
unsigned int res32;
unsigned long long res64;
uint32_t res32;
uint64_t res64;
/*
* Store byte combinations
@ -328,30 +313,30 @@ int main()
* Predicated word stores
*/
n.w[0] = ~0;
res32 = cancel_sw_lb(0, &n.w[0], &n.b[0], 0x12345678);
res32 = cancel_sw_lb(false, &n.w[0], &n.b[0], 0x12345678);
check32(res32, 0xffffffff);
n.w[0] = ~0;
res32 = cancel_sw_lb(1, &n.w[0], &n.b[0], 0x12345687);
res32 = cancel_sw_lb(true, &n.w[0], &n.b[0], 0x12345687);
check32(res32, 0xffffff87);
/*
* Predicated double stores
*/
n.d[0] = ~0LL;
res64 = cancel_sw_ld(0, &n.w[0], &n.d[0], 0x12345678);
res64 = cancel_sw_ld(false, &n.w[0], &n.d[0], 0x12345678);
check64(res64, 0xffffffffffffffffLL);
n.d[0] = ~0LL;
res64 = cancel_sw_ld(1, &n.w[0], &n.d[0], 0x12345678);
res64 = cancel_sw_ld(true, &n.w[0], &n.d[0], 0x12345678);
check64(res64, 0xffffffff12345678LL);
n.d[0] = ~0LL;
res64 = cancel_sw_ld(0, &n.w[1], &n.d[0], 0x12345678);
res64 = cancel_sw_ld(false, &n.w[1], &n.d[0], 0x12345678);
check64(res64, 0xffffffffffffffffLL);
n.d[0] = ~0LL;
res64 = cancel_sw_ld(1, &n.w[1], &n.d[0], 0x12345678);
res64 = cancel_sw_ld(true, &n.w[1], &n.d[0], 0x12345678);
check64(res64, 0x12345678ffffffffLL);
/*
@ -392,45 +377,45 @@ int main()
check64(res64, 0xffffffffffffffffLL);
n.w[0] = ~0;
res32 = pred_lw_sw(0, &n.w[0], &n.w[0], 0x12345678, 0xc0ffeeda);
res32 = pred_lw_sw(false, &n.w[0], &n.w[0], 0x12345678, 0xc0ffeeda);
check32(res32, 0x12345678);
check32(n.w[0], 0xc0ffeeda);
n.w[0] = ~0;
res32 = pred_lw_sw(1, &n.w[0], &n.w[0], 0x12345678, 0xc0ffeeda);
res32 = pred_lw_sw(true, &n.w[0], &n.w[0], 0x12345678, 0xc0ffeeda);
check32(res32, 0xc0ffeeda);
check32(n.w[0], 0xc0ffeeda);
n.w[0] = ~0;
res32 = pred_lw_sw_pi(0, &n.w[0], &n.w[0], 0x12345678, 0xc0ffeeda);
res32 = pred_lw_sw_pi(false, &n.w[0], &n.w[0], 0x12345678, 0xc0ffeeda);
check32(res32, 0x12345678);
check32(n.w[0], 0xc0ffeeda);
n.w[0] = ~0;
res32 = pred_lw_sw_pi(1, &n.w[0], &n.w[0], 0x12345678, 0xc0ffeeda);
res32 = pred_lw_sw_pi(true, &n.w[0], &n.w[0], 0x12345678, 0xc0ffeeda);
check32(res32, 0xc0ffeeda);
check32(n.w[0], 0xc0ffeeda);
n.d[0] = ~0LL;
res64 = pred_ld_sd(0, &n.d[0], &n.d[0],
res64 = pred_ld_sd(false, &n.d[0], &n.d[0],
0x1234567812345678LL, 0xc0ffeedac0ffeedaLL);
check64(res64, 0x1234567812345678LL);
check64(n.d[0], 0xc0ffeedac0ffeedaLL);
n.d[0] = ~0LL;
res64 = pred_ld_sd(1, &n.d[0], &n.d[0],
res64 = pred_ld_sd(true, &n.d[0], &n.d[0],
0x1234567812345678LL, 0xc0ffeedac0ffeedaLL);
check64(res64, 0xc0ffeedac0ffeedaLL);
check64(n.d[0], 0xc0ffeedac0ffeedaLL);
n.d[0] = ~0LL;
res64 = pred_ld_sd_pi(0, &n.d[0], &n.d[0],
res64 = pred_ld_sd_pi(false, &n.d[0], &n.d[0],
0x1234567812345678LL, 0xc0ffeedac0ffeedaLL);
check64(res64, 0x1234567812345678LL);
check64(n.d[0], 0xc0ffeedac0ffeedaLL);
n.d[0] = ~0LL;
res64 = pred_ld_sd_pi(1, &n.d[0], &n.d[0],
res64 = pred_ld_sd_pi(true, &n.d[0], &n.d[0],
0x1234567812345678LL, 0xc0ffeedac0ffeedaLL);
check64(res64, 0xc0ffeedac0ffeedaLL);
check64(n.d[0], 0xc0ffeedac0ffeedaLL);

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -34,6 +34,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
@ -41,49 +43,31 @@
#include <signal.h>
int err;
int segv_caught;
#include "hex_test.h"
bool segv_caught;
#define SHOULD_NOT_CHANGE_VAL 5
int should_not_change = SHOULD_NOT_CHANGE_VAL;
int32_t should_not_change = SHOULD_NOT_CHANGE_VAL;
#define OK_TO_CHANGE_VAL 13
int ok_to_change = OK_TO_CHANGE_VAL;
static void __check(const char *filename, int line, int x, int expect)
{
if (x != expect) {
printf("ERROR %s:%d - %d != %d\n",
filename, line, x, expect);
err++;
}
}
#define check(x, expect) __check(__FILE__, __LINE__, (x), (expect))
static void __chk_error(const char *filename, int line, int ret)
{
if (ret < 0) {
printf("ERROR %s:%d - %d\n", filename, line, ret);
err++;
}
}
#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
int32_t ok_to_change = OK_TO_CHANGE_VAL;
jmp_buf jmp_env;
static void sig_segv(int sig, siginfo_t *info, void *puc)
{
check(sig, SIGSEGV);
segv_caught = 1;
check32(sig, SIGSEGV);
segv_caught = true;
longjmp(jmp_env, 1);
}
int main()
{
struct sigaction act;
int dummy32;
long long dummy64;
int32_t dummy32;
int64_t dummy64;
void *p;
/* SIGSEGV test */
@ -106,8 +90,8 @@ int main()
act.sa_flags = 0;
chk_error(sigaction(SIGSEGV, &act, NULL));
check(segv_caught, 1);
check(should_not_change, SHOULD_NOT_CHANGE_VAL);
check32(segv_caught, true);
check32(should_not_change, SHOULD_NOT_CHANGE_VAL);
/*
* Check that a predicated load where the predicate is false doesn't
@ -122,7 +106,7 @@ int main()
"}:mem_noshuf\n\t"
: "=r"(dummy32) : : "r18", "r19", "p0", "memory");
check(ok_to_change, 7);
check32(ok_to_change, 7);
/*
* Also check that the post-increment doesn't happen when the
@ -138,8 +122,8 @@ int main()
"}:mem_noshuf\n\t"
: "+r"(p), "=r"(dummy64) : : "r18", "p0", "memory");
check(ok_to_change, 9);
check((int)p, (int)NULL);
check32(ok_to_change, 9);
check32((int)p, (int)NULL);
puts(err ? "FAIL" : "PASS");
return err ? EXIT_FAILURE : EXIT_SUCCESS;

View File

@ -16,16 +16,16 @@
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
int err;
#include "hex_test.h"
#define CORE_HAS_CABAC (__HEXAGON_ARCH__ <= 71)
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
static inline void S4_storerhnew_rr(void *p, int index, uint16_t v)
{
asm volatile("{\n\t"
@ -76,7 +76,7 @@ static inline void *S4_storerinew_ap(uint32_t v)
return ret;
}
static inline void S4_storeirbt_io(void *p, int pred)
static inline void S4_storeirbt_io(void *p, bool pred)
{
asm volatile("p0 = cmp.eq(%0, #1)\n\t"
"if (p0) memb(%1+#4)=#27\n\t"
@ -84,7 +84,7 @@ static inline void S4_storeirbt_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirbf_io(void *p, int pred)
static inline void S4_storeirbf_io(void *p, bool pred)
{
asm volatile("p0 = cmp.eq(%0, #1)\n\t"
"if (!p0) memb(%1+#4)=#27\n\t"
@ -92,7 +92,7 @@ static inline void S4_storeirbf_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirbtnew_io(void *p, int pred)
static inline void S4_storeirbtnew_io(void *p, bool pred)
{
asm volatile("{\n\t"
" p0 = cmp.eq(%0, #1)\n\t"
@ -102,7 +102,7 @@ static inline void S4_storeirbtnew_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirbfnew_io(void *p, int pred)
static inline void S4_storeirbfnew_io(void *p, bool pred)
{
asm volatile("{\n\t"
" p0 = cmp.eq(%0, #1)\n\t"
@ -112,7 +112,7 @@ static inline void S4_storeirbfnew_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirht_io(void *p, int pred)
static inline void S4_storeirht_io(void *p, bool pred)
{
asm volatile("p0 = cmp.eq(%0, #1)\n\t"
"if (p0) memh(%1+#4)=#27\n\t"
@ -120,7 +120,7 @@ static inline void S4_storeirht_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirhf_io(void *p, int pred)
static inline void S4_storeirhf_io(void *p, bool pred)
{
asm volatile("p0 = cmp.eq(%0, #1)\n\t"
"if (!p0) memh(%1+#4)=#27\n\t"
@ -128,7 +128,7 @@ static inline void S4_storeirhf_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirhtnew_io(void *p, int pred)
static inline void S4_storeirhtnew_io(void *p, bool pred)
{
asm volatile("{\n\t"
" p0 = cmp.eq(%0, #1)\n\t"
@ -138,7 +138,7 @@ static inline void S4_storeirhtnew_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirhfnew_io(void *p, int pred)
static inline void S4_storeirhfnew_io(void *p, bool pred)
{
asm volatile("{\n\t"
" p0 = cmp.eq(%0, #1)\n\t"
@ -148,7 +148,7 @@ static inline void S4_storeirhfnew_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirit_io(void *p, int pred)
static inline void S4_storeirit_io(void *p, bool pred)
{
asm volatile("p0 = cmp.eq(%0, #1)\n\t"
"if (p0) memw(%1+#4)=#27\n\t"
@ -156,7 +156,7 @@ static inline void S4_storeirit_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirif_io(void *p, int pred)
static inline void S4_storeirif_io(void *p, bool pred)
{
asm volatile("p0 = cmp.eq(%0, #1)\n\t"
"if (!p0) memw(%1+#4)=#27\n\t"
@ -164,7 +164,7 @@ static inline void S4_storeirif_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeiritnew_io(void *p, int pred)
static inline void S4_storeiritnew_io(void *p, bool pred)
{
asm volatile("{\n\t"
" p0 = cmp.eq(%0, #1)\n\t"
@ -174,7 +174,7 @@ static inline void S4_storeiritnew_io(void *p, int pred)
: "p0", "memory");
}
static inline void S4_storeirifnew_io(void *p, int pred)
static inline void S4_storeirifnew_io(void *p, bool pred)
{
asm volatile("{\n\t"
" p0 = cmp.eq(%0, #1)\n\t"
@ -184,9 +184,9 @@ static inline void S4_storeirifnew_io(void *p, int pred)
: "p0", "memory");
}
static int L2_ploadrifnew_pi(void *p, int pred)
static int32_t L2_ploadrifnew_pi(void *p, bool pred)
{
int result;
int32_t result;
asm volatile("%0 = #31\n\t"
"{\n\t"
" p0 = cmp.eq(%2, #1)\n\t"
@ -203,9 +203,9 @@ static int L2_ploadrifnew_pi(void *p, int pred)
* account for auto-anding. Then, we can do the predicated
* jump.
*/
static inline int cmpnd_cmp_jump(void)
static inline int32_t cmpnd_cmp_jump(void)
{
int retval;
int32_t retval;
asm ("r5 = #7\n\t"
"r6 = #9\n\t"
"{\n\t"
@ -222,9 +222,9 @@ static inline int cmpnd_cmp_jump(void)
return retval;
}
static inline int test_clrtnew(int arg1, int old_val)
static inline int32_t test_clrtnew(int32_t arg1, int32_t old_val)
{
int ret;
int32_t ret;
asm volatile("r5 = %2\n\t"
"{\n\t"
"p0 = cmp.eq(%1, #1)\n\t"
@ -237,36 +237,16 @@ static inline int test_clrtnew(int arg1, int old_val)
return ret;
}
int err;
static void check(int val, int expect)
{
if (val != expect) {
printf("ERROR: 0x%04x != 0x%04x\n", val, expect);
err++;
}
}
#if CORE_HAS_CABAC
static void check64(long long val, long long expect)
{
if (val != expect) {
printf("ERROR: 0x%016llx != 0x%016llx\n", val, expect);
err++;
}
}
#endif
uint32_t init[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
uint32_t array[10];
uint32_t early_exit;
bool early_exit;
/*
* Write this as a function because we can't guarantee the compiler will
* allocate a frame with just the SL2_return_tnew packet.
*/
static void SL2_return_tnew(int x);
static void SL2_return_tnew(bool pred);
asm ("SL2_return_tnew:\n\t"
" allocframe(#0)\n\t"
" r1 = #1\n\t"
@ -280,9 +260,9 @@ asm ("SL2_return_tnew:\n\t"
" dealloc_return\n\t"
);
static long long creg_pair(int x, int y)
static int64_t creg_pair(int32_t x, int32_t y)
{
long long retval;
int64_t retval;
asm ("m0 = %1\n\t"
"m1 = %2\n\t"
"%0 = c7:6\n\t"
@ -291,9 +271,9 @@ static long long creg_pair(int x, int y)
}
#if CORE_HAS_CABAC
static long long decbin(long long x, long long y, int *pred)
static int64_t decbin(int64_t x, int64_t y, bool *pred)
{
long long retval;
int64_t retval;
asm ("%0 = decbin(%2, %3)\n\t"
"%1 = p0\n\t"
: "=r"(retval), "=r"(*pred)
@ -303,9 +283,9 @@ static long long decbin(long long x, long long y, int *pred)
#endif
/* Check that predicates are auto-and'ed in a packet */
static int auto_and(void)
static bool auto_and(void)
{
int retval;
bool retval;
asm ("r5 = #1\n\t"
"{\n\t"
" p0 = cmp.eq(r1, #1)\n\t"
@ -320,7 +300,7 @@ static int auto_and(void)
void test_lsbnew(void)
{
int result;
int32_t result;
asm("r0 = #2\n\t"
"r1 = #5\n\t"
@ -330,7 +310,7 @@ void test_lsbnew(void)
"}\n\t"
"%0 = r1\n\t"
: "=r"(result) :: "r0", "r1", "p0");
check(result, 5);
check32(result, 5);
}
void test_l2fetch(void)
@ -340,226 +320,224 @@ void test_l2fetch(void)
"l2fetch(r0, r3:2)\n\t");
}
static inline int ct0(uint32_t x)
static inline int32_t ct0(uint32_t x)
{
int res;
int32_t res;
asm("%0 = ct0(%1)\n\t" : "=r"(res) : "r"(x));
return res;
}
static inline int ct1(uint32_t x)
static inline int32_t ct1(uint32_t x)
{
int res;
int32_t res;
asm("%0 = ct1(%1)\n\t" : "=r"(res) : "r"(x));
return res;
}
static inline int ct0p(uint64_t x)
static inline int32_t ct0p(uint64_t x)
{
int res;
int32_t res;
asm("%0 = ct0(%1)\n\t" : "=r"(res) : "r"(x));
return res;
}
static inline int ct1p(uint64_t x)
static inline int32_t ct1p(uint64_t x)
{
int res;
int32_t res;
asm("%0 = ct1(%1)\n\t" : "=r"(res) : "r"(x));
return res;
}
void test_count_trailing_zeros_ones(void)
{
check(ct0(0x0000000f), 0);
check(ct0(0x00000000), 32);
check(ct0(0x000000f0), 4);
check32(ct0(0x0000000f), 0);
check32(ct0(0x00000000), 32);
check32(ct0(0x000000f0), 4);
check(ct1(0x000000f0), 0);
check(ct1(0x0000000f), 4);
check(ct1(0x00000000), 0);
check(ct1(0xffffffff), 32);
check32(ct1(0x000000f0), 0);
check32(ct1(0x0000000f), 4);
check32(ct1(0x00000000), 0);
check32(ct1(0xffffffff), 32);
check(ct0p(0x000000000000000fULL), 0);
check(ct0p(0x0000000000000000ULL), 64);
check(ct0p(0x00000000000000f0ULL), 4);
check32(ct0p(0x000000000000000fULL), 0);
check32(ct0p(0x0000000000000000ULL), 64);
check32(ct0p(0x00000000000000f0ULL), 4);
check(ct1p(0x00000000000000f0ULL), 0);
check(ct1p(0x000000000000000fULL), 4);
check(ct1p(0x0000000000000000ULL), 0);
check(ct1p(0xffffffffffffffffULL), 64);
check(ct1p(0xffffffffff0fffffULL), 20);
check(ct1p(0xffffff0fffffffffULL), 36);
check32(ct1p(0x00000000000000f0ULL), 0);
check32(ct1p(0x000000000000000fULL), 4);
check32(ct1p(0x0000000000000000ULL), 0);
check32(ct1p(0xffffffffffffffffULL), 64);
check32(ct1p(0xffffffffff0fffffULL), 20);
check32(ct1p(0xffffff0fffffffffULL), 36);
}
static inline int dpmpyss_rnd_s0(int x, int y)
static inline int32_t dpmpyss_rnd_s0(int32_t x, int32_t y)
{
int res;
int32_t res;
asm("%0 = mpy(%1, %2):rnd\n\t" : "=r"(res) : "r"(x), "r"(y));
return res;
}
void test_dpmpyss_rnd_s0(void)
{
check(dpmpyss_rnd_s0(-1, 0x80000000), 1);
check(dpmpyss_rnd_s0(0, 0x80000000), 0);
check(dpmpyss_rnd_s0(1, 0x80000000), 0);
check(dpmpyss_rnd_s0(0x7fffffff, 0x80000000), 0xc0000001);
check(dpmpyss_rnd_s0(0x80000000, -1), 1);
check(dpmpyss_rnd_s0(-1, -1), 0);
check(dpmpyss_rnd_s0(0, -1), 0);
check(dpmpyss_rnd_s0(1, -1), 0);
check(dpmpyss_rnd_s0(0x7fffffff, -1), 0);
check(dpmpyss_rnd_s0(0x80000000, 0), 0);
check(dpmpyss_rnd_s0(-1, 0), 0);
check(dpmpyss_rnd_s0(0, 0), 0);
check(dpmpyss_rnd_s0(1, 0), 0);
check(dpmpyss_rnd_s0(-1, -1), 0);
check(dpmpyss_rnd_s0(0, -1), 0);
check(dpmpyss_rnd_s0(1, -1), 0);
check(dpmpyss_rnd_s0(0x7fffffff, 1), 0);
check(dpmpyss_rnd_s0(0x80000000, 0x7fffffff), 0xc0000001);
check(dpmpyss_rnd_s0(-1, 0x7fffffff), 0);
check(dpmpyss_rnd_s0(0, 0x7fffffff), 0);
check(dpmpyss_rnd_s0(1, 0x7fffffff), 0);
check(dpmpyss_rnd_s0(0x7fffffff, 0x7fffffff), 0x3fffffff);
check32(dpmpyss_rnd_s0(-1, 0x80000000), 1);
check32(dpmpyss_rnd_s0(0, 0x80000000), 0);
check32(dpmpyss_rnd_s0(1, 0x80000000), 0);
check32(dpmpyss_rnd_s0(0x7fffffff, 0x80000000), 0xc0000001);
check32(dpmpyss_rnd_s0(0x80000000, -1), 1);
check32(dpmpyss_rnd_s0(-1, -1), 0);
check32(dpmpyss_rnd_s0(0, -1), 0);
check32(dpmpyss_rnd_s0(1, -1), 0);
check32(dpmpyss_rnd_s0(0x7fffffff, -1), 0);
check32(dpmpyss_rnd_s0(0x80000000, 0), 0);
check32(dpmpyss_rnd_s0(-1, 0), 0);
check32(dpmpyss_rnd_s0(0, 0), 0);
check32(dpmpyss_rnd_s0(1, 0), 0);
check32(dpmpyss_rnd_s0(-1, -1), 0);
check32(dpmpyss_rnd_s0(0, -1), 0);
check32(dpmpyss_rnd_s0(1, -1), 0);
check32(dpmpyss_rnd_s0(0x7fffffff, 1), 0);
check32(dpmpyss_rnd_s0(0x80000000, 0x7fffffff), 0xc0000001);
check32(dpmpyss_rnd_s0(-1, 0x7fffffff), 0);
check32(dpmpyss_rnd_s0(0, 0x7fffffff), 0);
check32(dpmpyss_rnd_s0(1, 0x7fffffff), 0);
check32(dpmpyss_rnd_s0(0x7fffffff, 0x7fffffff), 0x3fffffff);
}
int main()
{
int res;
#if CORE_HAS_CABAC
long long res64;
int pred;
#endif
int32_t res;
int64_t res64;
bool pred;
memcpy(array, init, sizeof(array));
S4_storerhnew_rr(array, 4, 0xffff);
check(array[4], 0xffff);
check32(array[4], 0xffff);
data = ~0;
check((uint32_t)S4_storerbnew_ap(0x12), (uint32_t)&data);
check(data, 0xffffff12);
checkp(S4_storerbnew_ap(0x12), &data);
check32(data, 0xffffff12);
data = ~0;
check((uint32_t)S4_storerhnew_ap(0x1234), (uint32_t)&data);
check(data, 0xffff1234);
checkp(S4_storerhnew_ap(0x1234), &data);
check32(data, 0xffff1234);
data = ~0;
check((uint32_t)S4_storerinew_ap(0x12345678), (uint32_t)&data);
check(data, 0x12345678);
checkp(S4_storerinew_ap(0x12345678), &data);
check32(data, 0x12345678);
/* Byte */
memcpy(array, init, sizeof(array));
S4_storeirbt_io(&array[1], 1);
check(array[2], 27);
S4_storeirbt_io(&array[2], 0);
check(array[3], 3);
S4_storeirbt_io(&array[1], true);
check32(array[2], 27);
S4_storeirbt_io(&array[2], false);
check32(array[3], 3);
memcpy(array, init, sizeof(array));
S4_storeirbf_io(&array[3], 0);
check(array[4], 27);
S4_storeirbf_io(&array[4], 1);
check(array[5], 5);
S4_storeirbf_io(&array[3], false);
check32(array[4], 27);
S4_storeirbf_io(&array[4], true);
check32(array[5], 5);
memcpy(array, init, sizeof(array));
S4_storeirbtnew_io(&array[5], 1);
check(array[6], 27);
S4_storeirbtnew_io(&array[6], 0);
check(array[7], 7);
S4_storeirbtnew_io(&array[5], true);
check32(array[6], 27);
S4_storeirbtnew_io(&array[6], false);
check32(array[7], 7);
memcpy(array, init, sizeof(array));
S4_storeirbfnew_io(&array[7], 0);
check(array[8], 27);
S4_storeirbfnew_io(&array[8], 1);
check(array[9], 9);
S4_storeirbfnew_io(&array[7], false);
check32(array[8], 27);
S4_storeirbfnew_io(&array[8], true);
check32(array[9], 9);
/* Half word */
memcpy(array, init, sizeof(array));
S4_storeirht_io(&array[1], 1);
check(array[2], 27);
S4_storeirht_io(&array[2], 0);
check(array[3], 3);
S4_storeirht_io(&array[1], true);
check32(array[2], 27);
S4_storeirht_io(&array[2], false);
check32(array[3], 3);
memcpy(array, init, sizeof(array));
S4_storeirhf_io(&array[3], 0);
check(array[4], 27);
S4_storeirhf_io(&array[4], 1);
check(array[5], 5);
S4_storeirhf_io(&array[3], false);
check32(array[4], 27);
S4_storeirhf_io(&array[4], true);
check32(array[5], 5);
memcpy(array, init, sizeof(array));
S4_storeirhtnew_io(&array[5], 1);
check(array[6], 27);
S4_storeirhtnew_io(&array[6], 0);
check(array[7], 7);
S4_storeirhtnew_io(&array[5], true);
check32(array[6], 27);
S4_storeirhtnew_io(&array[6], false);
check32(array[7], 7);
memcpy(array, init, sizeof(array));
S4_storeirhfnew_io(&array[7], 0);
check(array[8], 27);
S4_storeirhfnew_io(&array[8], 1);
check(array[9], 9);
S4_storeirhfnew_io(&array[7], false);
check32(array[8], 27);
S4_storeirhfnew_io(&array[8], true);
check32(array[9], 9);
/* Word */
memcpy(array, init, sizeof(array));
S4_storeirit_io(&array[1], 1);
check(array[2], 27);
S4_storeirit_io(&array[2], 0);
check(array[3], 3);
S4_storeirit_io(&array[1], true);
check32(array[2], 27);
S4_storeirit_io(&array[2], false);
check32(array[3], 3);
memcpy(array, init, sizeof(array));
S4_storeirif_io(&array[3], 0);
check(array[4], 27);
S4_storeirif_io(&array[4], 1);
check(array[5], 5);
S4_storeirif_io(&array[3], false);
check32(array[4], 27);
S4_storeirif_io(&array[4], true);
check32(array[5], 5);
memcpy(array, init, sizeof(array));
S4_storeiritnew_io(&array[5], 1);
check(array[6], 27);
S4_storeiritnew_io(&array[6], 0);
check(array[7], 7);
S4_storeiritnew_io(&array[5], true);
check32(array[6], 27);
S4_storeiritnew_io(&array[6], false);
check32(array[7], 7);
memcpy(array, init, sizeof(array));
S4_storeirifnew_io(&array[7], 0);
check(array[8], 27);
S4_storeirifnew_io(&array[8], 1);
check(array[9], 9);
S4_storeirifnew_io(&array[7], false);
check32(array[8], 27);
S4_storeirifnew_io(&array[8], true);
check32(array[9], 9);
memcpy(array, init, sizeof(array));
res = L2_ploadrifnew_pi(&array[6], 0);
check(res, 6);
res = L2_ploadrifnew_pi(&array[7], 1);
check(res, 31);
res = L2_ploadrifnew_pi(&array[6], false);
check32(res, 6);
res = L2_ploadrifnew_pi(&array[7], true);
check32(res, 31);
int x = cmpnd_cmp_jump();
check(x, 12);
res = cmpnd_cmp_jump();
check32(res, 12);
SL2_return_tnew(0);
check(early_exit, 0);
SL2_return_tnew(1);
check(early_exit, 1);
SL2_return_tnew(false);
check32(early_exit, false);
SL2_return_tnew(true);
check32(early_exit, true);
long long pair = creg_pair(5, 7);
check((int)pair, 5);
check((int)(pair >> 32), 7);
res64 = creg_pair(5, 7);
check32((int32_t)res64, 5);
check32((int32_t)(res64 >> 32), 7);
res = test_clrtnew(1, 7);
check(res, 0);
check32(res, 0);
res = test_clrtnew(2, 7);
check(res, 7);
check32(res, 7);
#if CORE_HAS_CABAC
res64 = decbin(0xf0f1f2f3f4f5f6f7LL, 0x7f6f5f4f3f2f1f0fLL, &pred);
check64(res64, 0x357980003700010cLL);
check(pred, 0);
check32(pred, false);
res64 = decbin(0xfLL, 0x1bLL, &pred);
check64(res64, 0x78000100LL);
check(pred, 1);
check32(pred, true);
#else
puts("Skipping cabac tests");
#endif
res = auto_and();
check(res, 0);
pred = auto_and();
check32(pred, false);
test_lsbnew();

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,11 +16,17 @@
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
static int sfrecipa(int Rs, int Rt, int *pred_result)
int err;
#include "hex_test.h"
static int32_t sfrecipa(int32_t Rs, int32_t Rt, bool *pred_result)
{
int result;
int predval;
int32_t result;
bool predval;
asm volatile("%0,p0 = sfrecipa(%2, %3)\n\t"
"%1 = p0\n\t"
@ -31,10 +37,10 @@ static int sfrecipa(int Rs, int Rt, int *pred_result)
return result;
}
static int sfinvsqrta(int Rs, int *pred_result)
static int32_t sfinvsqrta(int32_t Rs, int32_t *pred_result)
{
int result;
int predval;
int32_t result;
int32_t predval;
asm volatile("%0,p0 = sfinvsqrta(%2)\n\t"
"%1 = p0\n\t"
@ -45,12 +51,12 @@ static int sfinvsqrta(int Rs, int *pred_result)
return result;
}
static long long vacsh(long long Rxx, long long Rss, long long Rtt,
int *pred_result, int *ovf_result)
static int64_t vacsh(int64_t Rxx, int64_t Rss, int64_t Rtt,
int *pred_result, bool *ovf_result)
{
long long result = Rxx;
int64_t result = Rxx;
int predval;
int usr;
uint32_t usr;
/*
* This instruction can set bit 0 (OVF/overflow) in usr
@ -70,11 +76,10 @@ static long long vacsh(long long Rxx, long long Rss, long long Rtt,
return result;
}
static long long vminub(long long Rtt, long long Rss,
int *pred_result)
static int64_t vminub(int64_t Rtt, int64_t Rss, int32_t *pred_result)
{
long long result;
int predval;
int64_t result;
int32_t predval;
asm volatile("%0,p0 = vminub(%2, %3)\n\t"
"%1 = p0\n\t"
@ -85,11 +90,11 @@ static long long vminub(long long Rtt, long long Rss,
return result;
}
static long long add_carry(long long Rss, long long Rtt,
int pred_in, int *pred_result)
static int64_t add_carry(int64_t Rss, int64_t Rtt,
int32_t pred_in, int32_t *pred_result)
{
long long result;
int predval = pred_in;
int64_t result;
int32_t predval = pred_in;
asm volatile("p0 = %1\n\t"
"%0 = add(%2, %3, p0):carry\n\t"
@ -101,11 +106,11 @@ static long long add_carry(long long Rss, long long Rtt,
return result;
}
static long long sub_carry(long long Rss, long long Rtt,
int pred_in, int *pred_result)
static int64_t sub_carry(int64_t Rss, int64_t Rtt,
int32_t pred_in, int32_t *pred_result)
{
long long result;
int predval = pred_in;
int64_t result;
int32_t predval = pred_in;
asm volatile("p0 = !cmp.eq(%1, #0)\n\t"
"%0 = sub(%2, %3, p0):carry\n\t"
@ -117,155 +122,129 @@ static long long sub_carry(long long Rss, long long Rtt,
return result;
}
int err;
static void check_ll(long long val, long long expect)
{
if (val != expect) {
printf("ERROR: 0x%016llx != 0x%016llx\n", val, expect);
err++;
}
}
static void check(int val, int expect)
{
if (val != expect) {
printf("ERROR: 0x%08x != 0x%08x\n", val, expect);
err++;
}
}
static void check_p(int val, int expect)
{
if (val != expect) {
printf("ERROR: 0x%02x != 0x%02x\n", val, expect);
err++;
}
}
static void test_sfrecipa()
{
int res;
int pred_result;
int32_t res;
bool pred_result;
res = sfrecipa(0x04030201, 0x05060708, &pred_result);
check(res, 0x59f38001);
check_p(pred_result, 0x00);
check32(res, 0x59f38001);
check32(pred_result, false);
}
static void test_sfinvsqrta()
{
int res;
int pred_result;
int32_t res;
int32_t pred_result;
res = sfinvsqrta(0x04030201, &pred_result);
check(res, 0x4d330000);
check_p(pred_result, 0xe0);
check32(res, 0x4d330000);
check32(pred_result, 0xe0);
res = sfinvsqrta(0x0, &pred_result);
check(res, 0x3f800000);
check_p(pred_result, 0x0);
check32(res, 0x3f800000);
check32(pred_result, 0x0);
}
static void test_vacsh()
{
long long res64;
int pred_result;
int ovf_result;
int64_t res64;
int32_t pred_result;
bool ovf_result;
res64 = vacsh(0x0004000300020001LL,
0x0001000200030004LL,
0x0000000000000000LL, &pred_result, &ovf_result);
check_ll(res64, 0x0004000300030004LL);
check_p(pred_result, 0xf0);
check(ovf_result, 0);
check64(res64, 0x0004000300030004LL);
check32(pred_result, 0xf0);
check32(ovf_result, false);
res64 = vacsh(0x0004000300020001LL,
0x0001000200030004LL,
0x000affff000d0000LL, &pred_result, &ovf_result);
check_ll(res64, 0x000e0003000f0004LL);
check_p(pred_result, 0xcc);
check(ovf_result, 0);
check64(res64, 0x000e0003000f0004LL);
check32(pred_result, 0xcc);
check32(ovf_result, false);
res64 = vacsh(0x00047fff00020001LL,
0x00017fff00030004LL,
0x000a0fff000d0000LL, &pred_result, &ovf_result);
check_ll(res64, 0x000e7fff000f0004LL);
check_p(pred_result, 0xfc);
check(ovf_result, 1);
check64(res64, 0x000e7fff000f0004LL);
check32(pred_result, 0xfc);
check32(ovf_result, true);
res64 = vacsh(0x0004000300020001LL,
0x0001000200030009LL,
0x000affff000d0001LL, &pred_result, &ovf_result);
check_ll(res64, 0x000e0003000f0008LL);
check_p(pred_result, 0xcc);
check(ovf_result, 0);
check64(res64, 0x000e0003000f0008LL);
check32(pred_result, 0xcc);
check32(ovf_result, false);
}
static void test_vminub()
{
long long res64;
int pred_result;
int64_t res64;
int32_t pred_result;
res64 = vminub(0x0807060504030201LL,
0x0102030405060708LL,
&pred_result);
check_ll(res64, 0x0102030404030201LL);
check_p(pred_result, 0xf0);
check64(res64, 0x0102030404030201LL);
check32(pred_result, 0xf0);
res64 = vminub(0x0802060405030701LL,
0x0107030504060208LL,
&pred_result);
check_ll(res64, 0x0102030404030201LL);
check_p(pred_result, 0xaa);
check64(res64, 0x0102030404030201LL);
check32(pred_result, 0xaa);
}
static void test_add_carry()
{
long long res64;
int pred_result;
int64_t res64;
int32_t pred_result;
res64 = add_carry(0x0000000000000000LL,
0xffffffffffffffffLL,
1, &pred_result);
check_ll(res64, 0x0000000000000000LL);
check_p(pred_result, 0xff);
check64(res64, 0x0000000000000000LL);
check32(pred_result, 0xff);
res64 = add_carry(0x0000000100000000LL,
0xffffffffffffffffLL,
0, &pred_result);
check_ll(res64, 0x00000000ffffffffLL);
check_p(pred_result, 0xff);
check64(res64, 0x00000000ffffffffLL);
check32(pred_result, 0xff);
res64 = add_carry(0x0000000100000000LL,
0xffffffffffffffffLL,
0, &pred_result);
check_ll(res64, 0x00000000ffffffffLL);
check_p(pred_result, 0xff);
check64(res64, 0x00000000ffffffffLL);
check32(pred_result, 0xff);
}
static void test_sub_carry()
{
long long res64;
int pred_result;
int64_t res64;
int32_t pred_result;
res64 = sub_carry(0x0000000000000000LL,
0x0000000000000000LL,
1, &pred_result);
check_ll(res64, 0x0000000000000000LL);
check_p(pred_result, 0xff);
check64(res64, 0x0000000000000000LL);
check32(pred_result, 0xff);
res64 = sub_carry(0x0000000100000000LL,
0x0000000000000000LL,
0, &pred_result);
check_ll(res64, 0x00000000ffffffffLL);
check_p(pred_result, 0xff);
check64(res64, 0x00000000ffffffffLL);
check32(pred_result, 0xff);
res64 = sub_carry(0x0000000100000000LL,
0x0000000000000000LL,
0, &pred_result);
check_ll(res64, 0x00000000ffffffffLL);
check_p(pred_result, 0xff);
check64(res64, 0x00000000ffffffffLL);
check32(pred_result, 0xff);
}
int main()

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2021-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2021-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -17,30 +17,21 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <setjmp.h>
#include <signal.h>
int err;
static void __check(const char *filename, int line, int x, int expect)
{
if (x != expect) {
printf("ERROR %s:%d - %d != %d\n",
filename, line, x, expect);
err++;
}
}
#include "hex_test.h"
#define check(x, expect) __check(__FILE__, __LINE__, (x), (expect))
static int satub(int src, int *p, int *ovf_result)
static int32_t satub(int32_t src, int32_t *p, bool *ovf_result)
{
int result;
int usr;
int32_t result;
uint32_t usr;
/*
* This instruction can set bit 0 (OVF/overflow) in usr
@ -65,30 +56,30 @@ static int satub(int src, int *p, int *ovf_result)
return result;
}
int read_usr_overflow(void)
bool read_usr_overflow(void)
{
int result;
asm volatile("%0 = usr\n\t" : "=r"(result));
return result & 1;
uint32_t usr;
asm volatile("%0 = usr\n\t" : "=r"(usr));
return usr & 1;
}
int get_usr_overflow(int usr)
bool get_usr_overflow(uint32_t usr)
{
return usr & 1;
}
int get_usr_fp_invalid(int usr)
bool get_usr_fp_invalid(uint32_t usr)
{
return (usr >> 1) & 1;
}
int get_usr_lpcfg(int usr)
int32_t get_usr_lpcfg(uint32_t usr)
{
return (usr >> 8) & 0x3;
}
jmp_buf jmp_env;
int usr_overflow;
bool usr_overflow;
static void sig_segv(int sig, siginfo_t *info, void *puc)
{
@ -98,9 +89,9 @@ static void sig_segv(int sig, siginfo_t *info, void *puc)
static void test_packet(void)
{
int convres;
int satres;
int usr;
int32_t convres;
int32_t satres;
uint32_t usr;
asm("r2 = usr\n\t"
"r2 = clrbit(r2, #0)\n\t" /* clear overflow bit */
@ -115,10 +106,10 @@ static void test_packet(void)
: "r"(0x6a051b86), "r"(0x0410eec0)
: "r2", "usr");
check(convres, 0xffffffff);
check(satres, 0x7f);
check(get_usr_overflow(usr), 1);
check(get_usr_fp_invalid(usr), 1);
check32(convres, 0xffffffff);
check32(satres, 0x7f);
check32(get_usr_overflow(usr), true);
check32(get_usr_fp_invalid(usr), true);
asm("r2 = usr\n\t"
"r2 = clrbit(r2, #0)\n\t" /* clear overflow bit */
@ -134,15 +125,15 @@ static void test_packet(void)
: "r"(0x0410eec0)
: "r2", "usr", "p3", "sa0", "lc0");
check(satres, 0x7f);
check(get_usr_overflow(usr), 1);
check(get_usr_lpcfg(usr), 2);
check32(satres, 0x7f);
check32(get_usr_overflow(usr), true);
check32(get_usr_lpcfg(usr), 2);
}
int main()
{
struct sigaction act;
int ovf;
bool ovf;
/* SIGSEGV test */
act.sa_sigaction = sig_segv;
@ -157,7 +148,7 @@ int main()
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
check(usr_overflow, 0);
check32(usr_overflow, false);
test_packet();

View File

@ -16,10 +16,15 @@
*/
#include <stdio.h>
#include <stdint.h>
static inline int preg_alias(int v0, int v1, int v2, int v3)
int err;
#include "hex_test.h"
static uint32_t preg_alias(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3)
{
int ret;
uint32_t ret;
asm volatile("p0 = %1\n\t"
"p1 = %2\n\t"
"p2 = %3\n\t"
@ -31,9 +36,9 @@ static inline int preg_alias(int v0, int v1, int v2, int v3)
return ret;
}
static inline int preg_alias_pair(int v0, int v1, int v2, int v3)
static uint32_t preg_alias_pair(uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3)
{
long long c54;
uint64_t c54;
asm volatile("p0 = %1\n\t"
"p1 = %2\n\t"
"p2 = %3\n\t"
@ -42,20 +47,20 @@ static inline int preg_alias_pair(int v0, int v1, int v2, int v3)
: "=r"(c54)
: "r"(v0), "r"(v1), "r"(v2), "r"(v3)
: "p0", "p1", "p2", "p3");
return (int)c54;
return (uint32_t)c54;
}
typedef union {
int creg;
uint32_t creg;
struct {
unsigned char p0;
unsigned char p1;
unsigned char p2;
unsigned char p3;
uint8_t p0;
uint8_t p1;
uint8_t p2;
uint8_t p3;
} pregs;
} PRegs;
static inline void creg_alias(int cval, PRegs *pregs)
static inline void creg_alias(uint32_t cval, PRegs *pregs)
{
asm("c4 = %4\n\t"
"%0 = p0\n\t"
@ -68,20 +73,10 @@ static inline void creg_alias(int cval, PRegs *pregs)
: "c4", "p0", "p1", "p2", "p3");
}
int err;
static void check(int val, int expect)
static inline void creg_alias_pair(uint32_t cval, PRegs *pregs)
{
if (val != expect) {
printf("ERROR: 0x%08x != 0x%08x\n", val, expect);
err++;
}
}
static inline void creg_alias_pair(unsigned int cval, PRegs *pregs)
{
unsigned long long cval_pair = (0xdeadbeefULL << 32) | cval;
int c5;
uint64_t cval_pair = (0xdeadbeefULL << 32) | cval;
uint32_t c5;
asm ("c5:4 = %5\n\t"
"%0 = p0\n\t"
@ -94,7 +89,7 @@ static inline void creg_alias_pair(unsigned int cval, PRegs *pregs)
: "r"(cval_pair)
: "c4", "c5", "p0", "p1", "p2", "p3");
check(c5, 0xdeadbeef);
check32(c5, 0xdeadbeef);
}
static void test_packet(void)
@ -104,8 +99,8 @@ static void test_packet(void)
* that are read during the packet.
*/
int result;
int old_val = 0x0000001c;
uint32_t result;
uint32_t old_val = 0x0000001c;
/* Test a predicated register transfer */
result = old_val;
@ -118,7 +113,7 @@ static void test_packet(void)
: "+r"(result)
: "r"(0xffffffff), "r"(0xff00ffff), "r"(0x837ed653)
: "c4", "p0", "p1", "p2", "p3");
check(result, old_val);
check32(result, old_val);
/* Test a predicated store */
result = 0xffffffff;
@ -130,73 +125,73 @@ static void test_packet(void)
:
: "r"(0), "r"(0xffffffff), "r"(&result)
: "c4", "p0", "p1", "p2", "p3", "memory");
check(result, 0x0);
check32(result, 0x0);
}
int main()
{
int c4;
uint32_t c4;
PRegs pregs;
c4 = preg_alias(0xff, 0x00, 0xff, 0x00);
check(c4, 0x00ff00ff);
check32(c4, 0x00ff00ff);
c4 = preg_alias(0xff, 0x00, 0x00, 0x00);
check(c4, 0x000000ff);
check32(c4, 0x000000ff);
c4 = preg_alias(0x00, 0xff, 0x00, 0x00);
check(c4, 0x0000ff00);
check32(c4, 0x0000ff00);
c4 = preg_alias(0x00, 0x00, 0xff, 0x00);
check(c4, 0x00ff0000);
check32(c4, 0x00ff0000);
c4 = preg_alias(0x00, 0x00, 0x00, 0xff);
check(c4, 0xff000000);
check32(c4, 0xff000000);
c4 = preg_alias(0xff, 0xff, 0xff, 0xff);
check(c4, 0xffffffff);
check32(c4, 0xffffffff);
c4 = preg_alias_pair(0xff, 0x00, 0xff, 0x00);
check(c4, 0x00ff00ff);
check32(c4, 0x00ff00ff);
c4 = preg_alias_pair(0xff, 0x00, 0x00, 0x00);
check(c4, 0x000000ff);
check32(c4, 0x000000ff);
c4 = preg_alias_pair(0x00, 0xff, 0x00, 0x00);
check(c4, 0x0000ff00);
check32(c4, 0x0000ff00);
c4 = preg_alias_pair(0x00, 0x00, 0xff, 0x00);
check(c4, 0x00ff0000);
check32(c4, 0x00ff0000);
c4 = preg_alias_pair(0x00, 0x00, 0x00, 0xff);
check(c4, 0xff000000);
check32(c4, 0xff000000);
c4 = preg_alias_pair(0xff, 0xff, 0xff, 0xff);
check(c4, 0xffffffff);
check32(c4, 0xffffffff);
creg_alias(0x00ff00ff, &pregs);
check(pregs.creg, 0x00ff00ff);
check32(pregs.creg, 0x00ff00ff);
creg_alias(0x00ffff00, &pregs);
check(pregs.creg, 0x00ffff00);
check32(pregs.creg, 0x00ffff00);
creg_alias(0x00000000, &pregs);
check(pregs.creg, 0x00000000);
check32(pregs.creg, 0x00000000);
creg_alias(0xff000000, &pregs);
check(pregs.creg, 0xff000000);
check32(pregs.creg, 0xff000000);
creg_alias(0x00ff0000, &pregs);
check(pregs.creg, 0x00ff0000);
check32(pregs.creg, 0x00ff0000);
creg_alias(0x0000ff00, &pregs);
check(pregs.creg, 0x0000ff00);
check32(pregs.creg, 0x0000ff00);
creg_alias(0x000000ff, &pregs);
check(pregs.creg, 0x000000ff);
check32(pregs.creg, 0x000000ff);
creg_alias(0xffffffff, &pregs);
check(pregs.creg, 0xffffffff);
check32(pregs.creg, 0xffffffff);
creg_alias_pair(0x00ff00ff, &pregs);
check(pregs.creg, 0x00ff00ff);
check32(pregs.creg, 0x00ff00ff);
creg_alias_pair(0x00ffff00, &pregs);
check(pregs.creg, 0x00ffff00);
check32(pregs.creg, 0x00ffff00);
creg_alias_pair(0x00000000, &pregs);
check(pregs.creg, 0x00000000);
check32(pregs.creg, 0x00000000);
creg_alias_pair(0xff000000, &pregs);
check(pregs.creg, 0xff000000);
check32(pregs.creg, 0xff000000);
creg_alias_pair(0x00ff0000, &pregs);
check(pregs.creg, 0x00ff0000);
check32(pregs.creg, 0x00ff0000);
creg_alias_pair(0x0000ff00, &pregs);
check(pregs.creg, 0x0000ff00);
check32(pregs.creg, 0x0000ff00);
creg_alias_pair(0x000000ff, &pregs);
check(pregs.creg, 0x000000ff);
check32(pregs.creg, 0x000000ff);
creg_alias_pair(0xffffffff, &pregs);
check(pregs.creg, 0xffffffff);
check32(pregs.creg, 0xffffffff);
test_packet();

View File

@ -32,16 +32,7 @@
int err;
static void __check(const char *filename, int line, int x, int expect)
{
if (x != expect) {
printf("ERROR %s:%d - 0x%08x != 0x%08x\n",
filename, line, x, expect);
err++;
}
}
#define check(x, expect) __check(__FILE__, __LINE__, (x), (expect))
#include "hex_test.h"
#define insert(RES, X, WIDTH, OFFSET) \
asm("r7 = %1\n\t" \
@ -54,11 +45,11 @@ static void test_insert(void)
uint32_t res;
insert(res, 0x12345678, 8, 1);
check(res, 0x123456f0);
check32(res, 0x123456f0);
insert(res, 0x12345678, 0, 1);
check(res, 0x12345678);
check32(res, 0x12345678);
insert(res, 0x12345678, 20, 16);
check(res, 0x56785678);
check32(res, 0x56785678);
}
static inline uint32_t insert_rp(uint32_t x, uint32_t width, uint32_t offset)
@ -75,12 +66,12 @@ static inline uint32_t insert_rp(uint32_t x, uint32_t width, uint32_t offset)
static void test_insert_rp(void)
{
check(insert_rp(0x12345678, 8, 1), 0x123456f0);
check(insert_rp(0x12345678, 63, 8), 0x34567878);
check(insert_rp(0x12345678, 127, 8), 0x34567878);
check(insert_rp(0x12345678, 8, 24), 0x78345678);
check(insert_rp(0x12345678, 8, 63), 0x12345678);
check(insert_rp(0x12345678, 8, 64), 0x00000000);
check32(insert_rp(0x12345678, 8, 1), 0x123456f0);
check32(insert_rp(0x12345678, 63, 8), 0x34567878);
check32(insert_rp(0x12345678, 127, 8), 0x34567878);
check32(insert_rp(0x12345678, 8, 24), 0x78345678);
check32(insert_rp(0x12345678, 8, 63), 0x12345678);
check32(insert_rp(0x12345678, 8, 64), 0x00000000);
}
static inline uint32_t asr_r_svw_trun(uint64_t x, uint32_t y)
@ -95,18 +86,18 @@ static inline uint32_t asr_r_svw_trun(uint64_t x, uint32_t y)
static void test_asr_r_svw_trun(void)
{
check(asr_r_svw_trun(0x1111111122222222ULL, 5),
0x88881111);
check(asr_r_svw_trun(0x1111111122222222ULL, 63),
0x00000000);
check(asr_r_svw_trun(0x1111111122222222ULL, 64),
0x00000000);
check(asr_r_svw_trun(0x1111111122222222ULL, 127),
0x22224444);
check(asr_r_svw_trun(0x1111111122222222ULL, 128),
0x11112222);
check(asr_r_svw_trun(0xffffffff22222222ULL, 128),
0xffff2222);
check32(asr_r_svw_trun(0x1111111122222222ULL, 5),
0x88881111);
check32(asr_r_svw_trun(0x1111111122222222ULL, 63),
0x00000000);
check32(asr_r_svw_trun(0x1111111122222222ULL, 64),
0x00000000);
check32(asr_r_svw_trun(0x1111111122222222ULL, 127),
0x22224444);
check32(asr_r_svw_trun(0x1111111122222222ULL, 128),
0x11112222);
check32(asr_r_svw_trun(0xffffffff22222222ULL, 128),
0xffff2222);
}
static inline uint32_t swiz(uint32_t x)
@ -121,7 +112,7 @@ static inline uint32_t swiz(uint32_t x)
static void test_swiz(void)
{
check(swiz(0x11223344), 0x44332211);
check32(swiz(0x11223344), 0x44332211);
}
int main()

View File

@ -1,6 +1,6 @@
/*
* Copyright(c) 2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,27 +21,7 @@
static int err;
#define check(N, EXPECT) \
do { \
uint64_t value = N; \
uint64_t expect = EXPECT; \
if (value != EXPECT) { \
printf("ERROR: \"%s\" 0x%04llx != 0x%04llx at %s:%d\n", #N, value, \
expect, __FILE__, __LINE__); \
err++; \
} \
} while (0)
#define check_ne(N, EXPECT) \
do { \
uint64_t value = N; \
uint64_t expect = EXPECT; \
if (value == EXPECT) { \
printf("ERROR: \"%s\" 0x%04llx == 0x%04llx at %s:%d\n", #N, value, \
expect, __FILE__, __LINE__); \
err++; \
} \
} while (0)
#include "hex_test.h"
#define WRITE_REG_NOCLOBBER(output, reg_name, input) \
asm volatile(reg_name " = %1\n\t" \
@ -85,35 +65,35 @@ static inline void write_control_registers(void)
uint32_t result = 0;
WRITE_REG_NOCLOBBER(result, "usr", 0xffffffff);
check(result, 0x3ecfff3f);
check32(result, 0x3ecfff3f);
WRITE_REG_NOCLOBBER(result, "gp", 0xffffffff);
check(result, 0xffffffc0);
check32(result, 0xffffffc0);
WRITE_REG_NOCLOBBER(result, "upcyclelo", 0xffffffff);
check(result, 0x00000000);
check32(result, 0x00000000);
WRITE_REG_NOCLOBBER(result, "upcyclehi", 0xffffffff);
check(result, 0x00000000);
check32(result, 0x00000000);
WRITE_REG_NOCLOBBER(result, "utimerlo", 0xffffffff);
check(result, 0x00000000);
check32(result, 0x00000000);
WRITE_REG_NOCLOBBER(result, "utimerhi", 0xffffffff);
check(result, 0x00000000);
check32(result, 0x00000000);
/*
* PC is special. Setting it to these values
* should cause a catastrophic failure.
*/
WRITE_REG_ENCODED(result, "pc", 0x00000000, PC_EQ_R0);
check_ne(result, 0x00000000);
check32_ne(result, 0x00000000);
WRITE_REG_ENCODED(result, "pc", 0x00000001, PC_EQ_R0);
check_ne(result, 0x00000001);
check32_ne(result, 0x00000001);
WRITE_REG_ENCODED(result, "pc", 0xffffffff, PC_EQ_R0);
check_ne(result, 0xffffffff);
check32_ne(result, 0xffffffff);
}
static inline void write_control_register_pairs(void)
@ -121,23 +101,23 @@ static inline void write_control_register_pairs(void)
uint64_t result = 0;
WRITE_REG_NOCLOBBER(result, "c11:10", 0xffffffffffffffff);
check(result, 0xffffffc0ffffffff);
check64(result, 0xffffffc0ffffffff);
WRITE_REG_NOCLOBBER(result, "c15:14", 0xffffffffffffffff);
check(result, 0x0000000000000000);
check64(result, 0x0000000000000000);
WRITE_REG_NOCLOBBER(result, "c31:30", 0xffffffffffffffff);
check(result, 0x0000000000000000);
check64(result, 0x0000000000000000);
WRITE_REG_PAIR_ENCODED(result, "c9:8", (uint64_t) 0x0000000000000000,
C9_8_EQ_R1_0);
check_ne(result, 0x000000000000000);
check64_ne(result, 0x000000000000000);
WRITE_REG_PAIR_ENCODED(result, "c9:8", 0x0000000100000000, C9_8_EQ_R1_0);
check_ne(result, 0x0000000100000000);
check64_ne(result, 0x0000000100000000);
WRITE_REG_PAIR_ENCODED(result, "c9:8", 0xffffffffffffffff, C9_8_EQ_R1_0);
check_ne(result, 0xffffffffffffffff);
check64_ne(result, 0xffffffffffffffff);
}
int main()

View File

@ -1,5 +1,5 @@
/*
* Copyright(c) 2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
* Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -24,35 +24,7 @@
int err;
static void __check(int line, uint32_t val, uint32_t expect)
{
if (val != expect) {
printf("ERROR at line %d: %d != %d\n", line, val, expect);
err++;
}
}
#define check(RES, EXP) __check(__LINE__, RES, EXP)
static void __check32(int line, uint32_t val, uint32_t expect)
{
if (val != expect) {
printf("ERROR at line %d: 0x%08x != 0x%08x\n", line, val, expect);
err++;
}
}
#define check32(RES, EXP) __check32(__LINE__, RES, EXP)
static void __check64(int line, uint64_t val, uint64_t expect)
{
if (val != expect) {
printf("ERROR at line %d: 0x%016llx != 0x%016llx\n", line, val, expect);
err++;
}
}
#define check64(RES, EXP) __check64(__LINE__, RES, EXP)
#include "hex_test.h"
/*
* Some of the instructions tested are only available on certain versions
@ -61,53 +33,6 @@ static void __check64(int line, uint64_t val, uint64_t expect)
#define CORE_HAS_AUDIO (__HEXAGON_ARCH__ >= 67 && defined(__HEXAGON_AUDIO__))
#define CORE_IS_V67 (__HEXAGON_ARCH__ >= 67)
/* Define the bits in Hexagon USR register */
#define USR_OVF_BIT 0 /* Sticky saturation overflow */
#define USR_FPINVF_BIT 1 /* IEEE FP invalid sticky flag */
#define USR_FPDBZF_BIT 2 /* IEEE FP divide-by-zero sticky flag */
#define USR_FPOVFF_BIT 3 /* IEEE FP overflow sticky flag */
#define USR_FPUNFF_BIT 4 /* IEEE FP underflow sticky flag */
#define USR_FPINPF_BIT 5 /* IEEE FP inexact sticky flag */
/* Corresponding values in USR */
#define USR_CLEAR 0
#define USR_OVF (1 << USR_OVF_BIT)
#define USR_FPINVF (1 << USR_FPINVF_BIT)
#define USR_FPDBZF (1 << USR_FPDBZF_BIT)
#define USR_FPOVFF (1 << USR_FPOVFF_BIT)
#define USR_FPUNFF (1 << USR_FPUNFF_BIT)
#define USR_FPINPF (1 << USR_FPINPF_BIT)
/* Some useful floating point values */
const uint32_t SF_INF = 0x7f800000;
const uint32_t SF_QNaN = 0x7fc00000;
const uint32_t SF_SNaN = 0x7fb00000;
const uint32_t SF_QNaN_neg = 0xffc00000;
const uint32_t SF_SNaN_neg = 0xffb00000;
const uint32_t SF_HEX_NaN = 0xffffffff;
const uint32_t SF_zero = 0x00000000;
const uint32_t SF_zero_neg = 0x80000000;
const uint32_t SF_one = 0x3f800000;
const uint32_t SF_one_recip = 0x3f7f0001; /* 0.9960... */
const uint32_t SF_one_invsqrta = 0x3f7f0000; /* 0.99609375 */
const uint32_t SF_two = 0x40000000;
const uint32_t SF_four = 0x40800000;
const uint32_t SF_small_neg = 0xab98fba8;
const uint32_t SF_large_pos = 0x5afa572e;
const uint64_t DF_QNaN = 0x7ff8000000000000ULL;
const uint64_t DF_SNaN = 0x7ff7000000000000ULL;
const uint64_t DF_QNaN_neg = 0xfff8000000000000ULL;
const uint64_t DF_SNaN_neg = 0xfff7000000000000ULL;
const uint64_t DF_HEX_NaN = 0xffffffffffffffffULL;
const uint64_t DF_zero = 0x0000000000000000ULL;
const uint64_t DF_zero_neg = 0x8000000000000000ULL;
const uint64_t DF_any = 0x3f80000000000000ULL;
const uint64_t DF_one = 0x3ff0000000000000ULL;
const uint64_t DF_one_hh = 0x3ff001ff80000000ULL; /* 1.00048... */
const uint64_t DF_small_neg = 0xbd731f7500000000ULL;
const uint64_t DF_large_pos = 0x7f80000000000001ULL;
/*
* Templates for functions to execute an instruction
*
@ -122,12 +47,6 @@ const uint64_t DF_large_pos = 0x7f80000000000001ULL;
* Xx read/write
*/
/* Clear bits 0-5 in USR */
#define CLEAR_USRBITS \
"r2 = usr\n\t" \
"r2 = and(r2, #0xffffffc0)\n\t" \
"usr = r2\n\t"
/* Template for instructions with one register operand */
#define FUNC_x_OP_x(RESTYPE, SRCTYPE, NAME, INSN) \
static RESTYPE NAME(SRCTYPE src, uint32_t *usr_result) \
@ -508,7 +427,7 @@ FUNC_Rp_OP_R(sfinvsqrta, "%0, p2 = sfinvsqrta(%3)")
uint32_t usr_result; \
result = FUNC(src, &usr_result); \
CHECKFN(result, RES); \
check(usr_result, USR_RES); \
check32(usr_result, USR_RES); \
} while (0)
#define TEST_R_OP_R(FUNC, SRC, RES, USR_RES) \
@ -532,8 +451,8 @@ TEST_x_OP_x(uint64_t, check64, uint32_t, FUNC, SRC, RES, USR_RES)
uint32_t usr_result; \
result = FUNC(src, &pred_result, &usr_result); \
CHECKFN(result, RES); \
check(pred_result, PRED_RES); \
check(usr_result, USR_RES); \
check32(pred_result, PRED_RES); \
check32(usr_result, USR_RES); \
} while (0)
#define TEST_Rp_OP_R(FUNC, SRC, RES, PRED_RES, USR_RES) \
@ -548,7 +467,7 @@ TEST_xp_OP_x(uint32_t, check32, uint32_t, FUNC, SRC, RES, PRED_RES, USR_RES)
uint32_t usr_result; \
result = FUNC(src1, src2, &usr_result); \
CHECKFN(result, RES); \
check(usr_result, USR_RES); \
check32(usr_result, USR_RES); \
} while (0)
#define TEST_P_OP_PP(FUNC, SRC1, SRC2, RES, USR_RES) \
@ -585,8 +504,8 @@ TEST_x_OP_xx(uint64_t, check64, uint64_t, uint32_t, \
uint32_t usr_result; \
result = FUNC(src1, src2, &pred_result, &usr_result); \
CHECKFN(result, RES); \
check(pred_result, PRED_RES); \
check(usr_result, USR_RES); \
check32(pred_result, PRED_RES); \
check32(usr_result, USR_RES); \
} while (0)
#define TEST_Rp_OP_RR(FUNC, SRC1, SRC2, RES, PRED_RES, USR_RES) \
@ -602,7 +521,7 @@ TEST_xp_OP_xx(uint32_t, check32, uint32_t, uint32_t, FUNC, SRC1, SRC2, \
uint32_t usr_result; \
result = FUNC(src1, src2, &usr_result); \
CHECKFN(result, RES); \
check(usr_result, USR_RES); \
check32(usr_result, USR_RES); \
} while (0)
#define TEST_R_OP_RI(FUNC, SRC1, SRC2, RES, USR_RES) \
@ -622,7 +541,7 @@ TEST_x_OP_xI(uint32_t, check64, uint64_t, \
uint32_t usr_result; \
result = FUNC(result, src1, src2, &usr_result); \
CHECKFN(result, RES); \
check(usr_result, USR_RES); \
check32(usr_result, USR_RES); \
} while (0)
#define TEST_XR_OP_RR(FUNC, RESIN, SRC1, SRC2, RES, USR_RES) \
@ -647,7 +566,7 @@ TEST_Xx_OP_xx(uint64_t, check64, uint32_t, uint32_t, \
uint32_t usr_result; \
result = FUNC(result, src1, src2, &pred_res, &usr_result); \
CHECKFN(result, RES); \
check(usr_result, USR_RES); \
check32(usr_result, USR_RES); \
} while (0)
#define TEST_XPp_OP_PP(FUNC, RESIN, SRC1, SRC2, RES, PRED_RES, USR_RES) \
@ -664,7 +583,7 @@ TEST_Xxp_OP_xx(uint64_t, check64, uint64_t, uint64_t, FUNC, RESIN, SRC1, SRC2, \
uint32_t usr_result; \
result = FUNC(result, src1, src2, pred, &usr_result); \
CHECKFN(result, RES); \
check(usr_result, USR_RES); \
check32(usr_result, USR_RES); \
} while (0)
#define TEST_XR_OP_RRp(FUNC, RESIN, SRC1, SRC2, PRED, RES, USR_RES) \
@ -679,8 +598,8 @@ TEST_Xx_OP_xxp(uint32_t, check32, uint32_t, uint32_t, \
SRC2TYPE src2 = SRC2; \
uint32_t usr_result; \
result = FUNC(src1, src2, &usr_result); \
check(result, RES); \
check(usr_result, USR_RES); \
check32(result, RES); \
check32(usr_result, USR_RES); \
} while (0)
#define TEST_CMP_RR(FUNC, SRC1, SRC2, RES, USR_RES) \