mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-11 09:56:29 +00:00
131 lines
3.7 KiB
C
131 lines
3.7 KiB
C
#include <stdio.h>
|
|
#include "opcodes.h"
|
|
|
|
/* The FLOGR insn reads from register R2 and writes to register R1 and
|
|
R1 + 1. So we need to distinguish three cases:
|
|
|
|
(1) All three registers R1, R1 + 1, and R2 are distinct
|
|
(2) R2 == R1
|
|
(3) R2 == R1 + 1
|
|
|
|
These are tested by flogr1, flogr2, and flogr3, respectively. */
|
|
|
|
/* Call FLOGR on INPUT. The results are returned through the parms. */
|
|
|
|
/* R2 != R1 && R2 != R1 + 1 */
|
|
void
|
|
flogr1(unsigned long input, unsigned long *bitpos, unsigned long *modval,
|
|
unsigned int *cc)
|
|
{
|
|
unsigned int psw;
|
|
register unsigned long value asm("4") = input;
|
|
|
|
asm volatile ( FLOGR(2,4)
|
|
"ipm %[psw]\n\t"
|
|
"stg 2, %[bitpos]\n\t"
|
|
"stg 3, %[modval]\n\t"
|
|
: [bitpos]"=m"(*bitpos), [modval]"=m"(*modval),
|
|
[psw]"=&d"(psw)
|
|
: [val] "d"(value)
|
|
: "2", "3", "cc");
|
|
|
|
*cc = psw >> 28;
|
|
#if 0
|
|
printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n",
|
|
value, *bitpos, *modval, *cc);
|
|
#endif
|
|
}
|
|
|
|
/* R2 == R1 */
|
|
void
|
|
flogr2(unsigned long input, unsigned long *bitpos, unsigned long *modval,
|
|
unsigned int *cc)
|
|
{
|
|
unsigned int psw;
|
|
register unsigned long value asm("2") = input;
|
|
|
|
asm volatile ( FLOGR(2,2)
|
|
"ipm %[psw]\n\t"
|
|
"stg 2, %[bitpos]\n\t"
|
|
"stg 3, %[modval]\n\t"
|
|
: [bitpos]"=m"(*bitpos), [modval]"=m"(*modval),
|
|
[psw]"=&d"(psw), [val] "+d"(value)
|
|
:
|
|
: "3", "cc");
|
|
|
|
*cc = psw >> 28;
|
|
#if 0
|
|
printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n",
|
|
value, *bitpos, *modval, *cc);
|
|
#endif
|
|
}
|
|
|
|
/* R2 == R1 + 1 */
|
|
void
|
|
flogr3(unsigned long input, unsigned long *bitpos, unsigned long *modval,
|
|
unsigned int *cc)
|
|
{
|
|
unsigned int psw;
|
|
register unsigned long value asm("3") = input;
|
|
|
|
asm volatile ( FLOGR(2,3)
|
|
"ipm %[psw]\n\t"
|
|
"stg 2, %[bitpos]\n\t"
|
|
"stg 3, %[modval]\n\t"
|
|
: [bitpos]"=m"(*bitpos), [modval]"=m"(*modval),
|
|
[psw]"=&d"(psw), [val] "+d"(value)
|
|
:
|
|
: "2", "cc");
|
|
|
|
*cc = psw >> 28;
|
|
#if 0
|
|
printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n",
|
|
value, *bitpos, *modval, *cc);
|
|
#endif
|
|
}
|
|
|
|
void
|
|
runtest(void (*func)(unsigned long, unsigned long *, unsigned long *,
|
|
unsigned int *))
|
|
{
|
|
unsigned long bitpos, modval, value;
|
|
unsigned int cc;
|
|
int i;
|
|
|
|
/* Value 0 is special */
|
|
value = 0;
|
|
func(value, &bitpos, &modval, &cc);
|
|
if (modval != 0) fprintf(stderr, "modval is wrong for %lx\n", value);
|
|
if (bitpos != 64) fprintf(stderr, "bitpos is wrong for %lx\n", value);
|
|
if (cc != 0) fprintf(stderr, "cc is wrong for %lx\n", value);
|
|
|
|
/* Test with exactly 1 bit set */
|
|
for (i = 0; i < 64; ++i) {
|
|
value = 1ull << i;
|
|
func(value, &bitpos, &modval, &cc);
|
|
if (modval != 0) fprintf(stderr, "modval is wrong for %lx\n", value);
|
|
if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value);
|
|
if (cc != 2) fprintf(stderr, "cc is wrong for %lx\n", value);
|
|
}
|
|
|
|
/* Test with all bits 1 right from first 1 bit */
|
|
for (i = 1; i < 64; ++i) {
|
|
value = 1ull << i;
|
|
value = value | (value - 1);
|
|
func(value, &bitpos, &modval, &cc);
|
|
if (modval != (value >> 1)) fprintf(stderr, "modval is wrong for %lx\n", value);
|
|
if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value);
|
|
if (cc != 2) fprintf(stderr, "cc is wrong for %lx\n", value);
|
|
}
|
|
}
|
|
|
|
|
|
int main()
|
|
{
|
|
runtest(flogr1);
|
|
runtest(flogr2);
|
|
runtest(flogr3);
|
|
|
|
return 0;
|
|
}
|