Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
728 changes: 655 additions & 73 deletions ppc64.risu

Large diffs are not rendered by default.

81 changes: 79 additions & 2 deletions risu_reginfo_ppc64.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "risu.h"
#include "risu_reginfo_ppc64.h"

#define CTR 35
#define XER 37
#define CCR 38

Expand Down Expand Up @@ -49,19 +50,32 @@ void reginfo_init(struct reginfo *ri, ucontext_t *uc)
memset(ri, 0, sizeof(*ri));

ri->faulting_insn = *((uint32_t *) uc->uc_mcontext.regs->nip);
ri->prev_insn = *((uint32_t *) (uc->uc_mcontext.regs->nip - 4));
ri->nip = uc->uc_mcontext.regs->nip - image_start_address;

for (i = 0; i < NGREG; i++) {
ri->gregs[i] = uc->uc_mcontext.gp_regs[i];
}

memcpy(ri->fpregs, uc->uc_mcontext.fp_regs, 32 * sizeof(double));
ri->fpscr = uc->uc_mcontext.fp_regs[32];
memcpy(&ri->fpscr, &uc->uc_mcontext.fp_regs[32], sizeof(uint64_t));
ri->fpscr &= ~0x40000; /* ignore FR bit */

memcpy(ri->vrregs.vrregs, uc->uc_mcontext.v_regs->vrregs,
sizeof(ri->vrregs.vrregs[0]) * 32);
ri->vrregs.vscr = uc->uc_mcontext.v_regs->vscr;
ri->vrregs.vrsave = uc->uc_mcontext.v_regs->vrsave;

for (i = 0; i < 32; i++) {
/*
* From sigcontext.h:
* "FPR/VSR 0-31 doubleword 0 is stored in fp_regs, and VMX/VSR 32-63
* is stored at the start of vmx_reserve. vmx_reserve is extended for
* backwards compatility to store VSR 0-31 doubleword 1 after the VMX
* registers and vscr/vrsave."
*/
ri->vsrreghalf[i] = uc->uc_mcontext.vmx_reserve[2 * NVRREG + 1 + i];
}
}

/* reginfo_is_eq: compare the reginfo structs, returns nonzero if equal */
Expand All @@ -78,11 +92,15 @@ int reginfo_is_eq(struct reginfo *m, struct reginfo *a)
}
}

if (m->gregs[CTR] != a->gregs[CTR]) {
return 0;
}

if (m->gregs[XER] != a->gregs[XER]) {
return 0;
}

if ((m->gregs[CCR] & 0x10) != (a->gregs[CCR] & 0x10)) {
if ((m->gregs[CCR]) != (a->gregs[CCR])) {
return 0;
}

Expand All @@ -92,6 +110,10 @@ int reginfo_is_eq(struct reginfo *m, struct reginfo *a)
}
}

if (m->fpscr != a->fpscr) {
return 0;
}

for (i = 0; i < 32; i++) {
if (m->vrregs.vrregs[i][0] != a->vrregs.vrregs[i][0] ||
m->vrregs.vrregs[i][1] != a->vrregs.vrregs[i][1] ||
Expand All @@ -100,6 +122,21 @@ int reginfo_is_eq(struct reginfo *m, struct reginfo *a)
return 0;
}
}

for (i = 0; i < 32; i++) {
if (m->vsrreghalf[i] != a->vsrreghalf[i]) {
return 0;
}
}

if (m->vrregs.vscr.vscr_word != a->vrregs.vscr.vscr_word) {
return 0;
}

if (m->vrregs.vrsave != a->vrregs.vrsave) {
return 0;
}

return 1;
}

Expand Down Expand Up @@ -143,6 +180,13 @@ int reginfo_dump(struct reginfo *ri, FILE * f)
ri->vrregs.vrregs[i][0], ri->vrregs.vrregs[i][1],
ri->vrregs.vrregs[i][2], ri->vrregs.vrregs[i][3]);
}
fprintf(f, "\tvscr: %8x\tvrsave: %8x\n", ri->vrregs.vscr.vscr_word,
ri->vrregs.vrsave);

for (i = 0; i < 32; i++) {
fprintf(f, "vsr%02d: %16lx, %16lx\n", i, ri->fpregs[i],
ri->vsrreghalf[i]);
}

return !ferror(f);
}
Expand All @@ -162,6 +206,11 @@ int reginfo_dump_mismatch(struct reginfo *m, struct reginfo *a, FILE *f)
}
}

if (m->gregs[CTR] != a->gregs[CTR]) {
fprintf(f, "Mismatch: CTR\n");
fprintf(f, "m: [%lx] != a: [%lx]\n", m->gregs[CTR], a->gregs[CTR]);
}

if (m->gregs[XER] != a->gregs[XER]) {
fprintf(f, "Mismatch: XER\n");
fprintf(f, "m: [%lx] != a: [%lx]\n", m->gregs[XER], a->gregs[XER]);
Expand All @@ -180,6 +229,11 @@ int reginfo_dump_mismatch(struct reginfo *m, struct reginfo *a, FILE *f)
}
}

if (m->fpscr != a->fpscr) {
fprintf(f, "Mismatch: FPSCR\n");
fprintf(f, "m: [0x%016lx] != a: [0x%016lx]\n", m->fpscr, a->fpscr);
}

for (i = 0; i < 32; i++) {
if (m->vrregs.vrregs[i][0] != a->vrregs.vrregs[i][0] ||
m->vrregs.vrregs[i][1] != a->vrregs.vrregs[i][1] ||
Expand All @@ -194,5 +248,28 @@ int reginfo_dump_mismatch(struct reginfo *m, struct reginfo *a, FILE *f)
a->vrregs.vrregs[i][2], a->vrregs.vrregs[i][3]);
}
}

if (m->vrregs.vscr.vscr_word != a->vrregs.vscr.vscr_word) {
fprintf(f, "Mismatch: VSCR\n");
fprintf(f, "m: [%8x] != a: [%8x]\n", m->vrregs.vscr.vscr_word,
a->vrregs.vscr.vscr_word);
}

if (m->vrregs.vrsave != a->vrregs.vrsave) {
fprintf(f, "Mismatch: VRSAVE\n");
fprintf(f, "m: [%8x] != a: [%8x]\n", m->vrregs.vrsave,
a->vrregs.vrsave);
}

for (i = 0; i < 32; i++) {
if (m->vsrreghalf[i] != a->vsrreghalf[i]) {
fprintf(f, "Mismatch: Register vsr%d\n", i);
fprintf(f, "m: [%16lx, %16lx] != a: [%16lx, %16lx]\n",
m->fpregs[i], m->vsrreghalf[i],
a->fpregs[i], a->vsrreghalf[i]);
return 0;
}
}

return !ferror(f);
}
1 change: 1 addition & 0 deletions risu_reginfo_ppc64.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct reginfo {
uint64_t fpregs[32];
uint64_t fpscr;
vrregset_t vrregs;
uint64_t vsrreghalf[32];
};

#endif /* RISU_REGINFO_PPC64LE_H */
15 changes: 11 additions & 4 deletions risugen
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ sub parse_config_file($)

my $fixedbits = 0;
my $fixedbitmask = 0;
my $bitpos = 32;
my $insnwidth = 32;
my $bitpos = 64;
my $insnwidth = 64;
my $seenblock = 0;

while (@bits) {
Expand Down Expand Up @@ -229,7 +229,10 @@ sub parse_config_file($)
push @fields, [ $var, $bitpos, $bitmask ];
}
}
if ($bitpos == 16) {
if ($bitpos == (64 - 32)) {
# normal/non-prefixed instruction
$insnwidth = 32;
} elsif ($bitpos == (64 - 16)) {
# assume this is a half-width thumb instruction
# Note that we don't fiddle with the bitmasks or positions,
# which means the generated insn will be in the high halfword!
Expand Down Expand Up @@ -310,6 +313,7 @@ Valid options:
Useful to test before support for FP is available.
--sve : enable sve floating point
--be : generate instructions in Big-Endian byte order (ppc64 only).
--vsx : initialize vector-scalar extension facility registers with random data (ppc64 only).
--help : print this message
EOT
}
Expand All @@ -321,6 +325,7 @@ sub main()
my $fpscr = 0;
my $fp_enabled = 1;
my $sve_enabled = 0;
my $vsx_enabled = 0;
my $big_endian = 0;
my ($infile, $outfile);

Expand All @@ -337,6 +342,7 @@ sub main()
}
},
"be" => sub { $big_endian = 1; },
"vsx" => sub { $vsx_enabled = 1; },
"no-fp" => sub { $fp_enabled = 0; },
"sve" => sub { $sve_enabled = 1; },
) or return 1;
Expand Down Expand Up @@ -372,7 +378,8 @@ sub main()
'keys' => \@insn_keys,
'arch' => $full_arch[0],
'subarch' => $full_arch[1] || '',
'bigendian' => $big_endian
'bigendian' => $big_endian,
'vsx_enabled' => $vsx_enabled
);

write_test_code(\%params);
Expand Down
3 changes: 2 additions & 1 deletion risugen_arm.pm
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,7 @@ sub gen_one_insn($$)

INSN: while(1) {
my ($forcecond, $rec) = @_;
my $insn = int(rand(0xffffffff));
my $insn = int(rand(0xffffffff)) << 32;
my $insnname = $rec->{name};
my $insnwidth = $rec->{width};
my $fixedbits = $rec->{fixedbits};
Expand Down Expand Up @@ -1005,6 +1005,7 @@ sub gen_one_insn($$)

# OK, we got a good one
$constraintfailures = 0;
$insn >>= 32;

my $basereg;

Expand Down
3 changes: 2 additions & 1 deletion risugen_m68k.pm
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ sub gen_one_insn($$)

INSN: while(1) {
my ($forcecond, $rec) = @_;
my $insn = int(rand(0xffffffff));
my $insn = int(rand(0xffffffff)) << 32;
my $insnname = $rec->{name};
my $insnwidth = $rec->{width};
my $fixedbits = $rec->{fixedbits};
Expand Down Expand Up @@ -142,6 +142,7 @@ sub gen_one_insn($$)

# OK, we got a good one
$constraintfailures = 0;
$insn >>= 32;

insn16($insn >> 16);
if ($insnwidth == 32) {
Expand Down
Loading