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>
This commit is contained in:
commit
9c9fff18c4
1
.mailmap
1
.mailmap
@ -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.
|
||||
|
@ -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/
|
||||
|
@ -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(
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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))
|
||||
|
@ -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]
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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++; \
|
||||
} \
|
||||
} \
|
||||
for (i = size; i < BUFSIZE; i++) { \
|
||||
if (BUF[i] != i) { \
|
||||
printf("ERROR(%3d): 0x%02" #FMT " != 0x%02x\n", i, BUF[i], i); \
|
||||
err++; \
|
||||
check64(BUF[i], circ_val_##SZ(i, inc, size)); \
|
||||
} \
|
||||
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"
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
145
tests/tcg/hexagon/hex_test.h
Normal file
145
tests/tcg/hexagon/hex_test.h
Normal 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
|
@ -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();
|
||||
|
@ -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)]); \
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,17 +86,17 @@ 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),
|
||||
check32(asr_r_svw_trun(0x1111111122222222ULL, 5),
|
||||
0x88881111);
|
||||
check(asr_r_svw_trun(0x1111111122222222ULL, 63),
|
||||
check32(asr_r_svw_trun(0x1111111122222222ULL, 63),
|
||||
0x00000000);
|
||||
check(asr_r_svw_trun(0x1111111122222222ULL, 64),
|
||||
check32(asr_r_svw_trun(0x1111111122222222ULL, 64),
|
||||
0x00000000);
|
||||
check(asr_r_svw_trun(0x1111111122222222ULL, 127),
|
||||
check32(asr_r_svw_trun(0x1111111122222222ULL, 127),
|
||||
0x22224444);
|
||||
check(asr_r_svw_trun(0x1111111122222222ULL, 128),
|
||||
check32(asr_r_svw_trun(0x1111111122222222ULL, 128),
|
||||
0x11112222);
|
||||
check(asr_r_svw_trun(0xffffffff22222222ULL, 128),
|
||||
check32(asr_r_svw_trun(0xffffffff22222222ULL, 128),
|
||||
0xffff2222);
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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) \
|
||||
|
Loading…
Reference in New Issue
Block a user