add oversampler

This commit is contained in:
2024-05-24 13:28:31 +02:00
parent e4a4a661a0
commit 989dba5a6b
484 changed files with 313937 additions and 0 deletions

View File

@@ -0,0 +1,285 @@
#ifndef _NSEEL_GLUE_PPC_H_
#define _NSEEL_GLUE_PPC_H_
#define GLUE_MAX_FPSTACK_SIZE 0 // no stack support
#define GLUE_MAX_JMPSIZE 30000 // maximum relative jump size for this arch (if not defined, any jump is possible)
// endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction.
// on PPC the offset needs to be from the start of the instruction (hence +4), and also the low two bits are flags so
// we make sure they are clear (they should always be clear, anyway, since we always generate 4 byte instructions)
#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((short *)(endOfInstruction))[-1] = ((offset) + 4) & 0xFFFC)
static const unsigned char GLUE_JMP_NC[] = { 0x48,0, 0, 0, }; // b <offset>
static const unsigned int GLUE_JMP_IF_P1_Z[]=
{
0x2f830000, //cmpwi cr7, r3, 0
0x419e0000, // beq cr7, offset-bytes-from-startofthisinstruction
};
static const unsigned int GLUE_JMP_IF_P1_NZ[]=
{
0x2f830000, //cmpwi cr7, r3, 0
0x409e0000, // bne cr7, offset-bytes-from-startofthisinstruction
};
#define GLUE_MOV_PX_DIRECTVALUE_SIZE 8
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
{
static const unsigned short tab[3][2] = {
{0x3C60, 0x6063}, // addis r3, r0, hw -- ori r3,r3, lw
{0x3DC0, 0x61CE}, // addis r14, r0, hw -- ori r14, r14, lw
{0x3DE0, 0x61EF}, // addis r15, r0, hw -- oris r15, r15, lw
};
unsigned int uv=(unsigned int)v;
unsigned short *p=(unsigned short *)b;
*p++ = tab[wv][0]; // addis rX, r0, hw
*p++ = (uv>>16)&0xffff;
*p++ = tab[wv][1]; // ori rX, rX, lw
*p++ = uv&0xffff;
}
// mflr r5
// stwu r5, -16(r1)
const static unsigned int GLUE_FUNC_ENTER[2] = { 0x7CA802A6, 0x94A1FFF0 };
#define GLUE_FUNC_ENTER_SIZE 8
// lwz r5, 0(r1)
// addi r1, r1, 16
// mtlr r5
const static unsigned int GLUE_FUNC_LEAVE[3] = { 0x80A10000, 0x38210010, 0x7CA803A6 };
#define GLUE_FUNC_LEAVE_SIZE 12
const static unsigned int GLUE_RET[]={0x4E800020}; // blr
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
{
const static unsigned int GLUE_SET_WTP_FROM_R17=0x7E308B78; // mr r16 (dest), r17 (src)
if (out) memcpy(out,&GLUE_SET_WTP_FROM_R17,sizeof(GLUE_SET_WTP_FROM_R17));
return sizeof(GLUE_SET_WTP_FROM_R17);
}
// stwu r3, -16(r1)
const static unsigned int GLUE_PUSH_P1[1]={ 0x9461FFF0};
#define GLUE_POP_PX_SIZE 8
static void GLUE_POP_PX(void *b, int wv)
{
static const unsigned int tab[3] ={
0x80610000, // lwz r3, 0(r1)
0x81c10000, // lwz r14, 0(r1)
0x81e10000, // lwz r15, 0(r1)
};
((unsigned int *)b)[0] = tab[wv];
((unsigned int *)b)[1] = 0x38210010; // addi r1,r1, 16
}
#define GLUE_SET_PX_FROM_P1_SIZE 4
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
{
static const unsigned int tab[3]={
0x7c631b78, // never used: mr r3, r3
0x7c6e1b78, // mr r14, r3
0x7c6f1b78, // mr r15, r3
};
*(unsigned int *)b = tab[wv];
}
// lfd f2, 0(r3)
// stfdu f2, -16(r1)
static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] = { 0xC8430000, 0xDC41FFF0 };
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
{
// lfd f2, 0(r1)
// addi r1,r1,16
// GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3)
// stfd f2, 0(r3)
if (buf)
{
unsigned int *bufptr = (unsigned int *)buf;
*bufptr++ = 0xC8410000;
*bufptr++ = 0x38210010;
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
*bufptr++ = 0xd8430000;
}
return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4;
}
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
{
// lfd f2, 0(r3)
// GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3)
// stfd f2, 0(r3)
if (buf)
{
unsigned int *bufptr = (unsigned int *)buf;
*bufptr++ = 0xc8430000;
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
*bufptr++ = 0xd8430000;
}
return 4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4;
}
static void GLUE_CALL_CODE(INT_PTR bp, INT_PTR cp, INT_PTR rt)
{
static const double consttab[] = {
NSEEL_CLOSEFACTOR,
4503601774854144.0 /* 0x43300000, 0x80000000, used for integer conversion*/,
};
// we could have r18 refer to the current user-stack pointer, someday, perhaps
__asm__(
"subi r1, r1, 128\n"
"stfd f31, 8(r1)\n"
"stfd f30, 16(r1)\n"
"stmw r13, 32(r1)\n"
"mtctr %0\n"
"mr r17, %1\n"
"mr r13, %2\n"
"lfd f31, 0(%3)\n"
"lfd f30, 8(%3)\n"
"subi r17, r17, 8\n"
"mflr r0\n"
"stw r0, 24(r1)\n"
"bctrl\n"
"lwz r0, 24(r1)\n"
"mtlr r0\n"
"lmw r13, 32(r1)\n"
"lfd f31, 8(r1)\n"
"lfd f30, 16(r1)\n"
"addi r1, r1, 128\n"
::"r" (cp), "r" (bp), "r" (rt), "r" (consttab));
};
static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
{
// 64 bit ppc would take some work
unsigned int *p=(unsigned int *)_p;
while ((p[0]&0x0000FFFF) != 0x0000dead &&
(p[1]&0x0000FFFF) != 0x0000beef) p++;
p[0] = (p[0]&0xFFFF0000) | (((newv)>>16)&0xFFFF);
p[1] = (p[1]&0xFFFF0000) | ((newv)&0xFFFF);
return (unsigned char *)(p+1);
}
#define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int)
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
{
static const unsigned int tab[3]={
0x7e038378, // mr r3, r16
0x7e0e8378, // mr r14, r16
0x7e0f8378, // mr r15, r16
};
*(unsigned int *)b = tab[wv];
}
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
{
// set r3 to destptr
// stfd f1, 0(r3)
if (buf)
{
unsigned int *bufptr = (unsigned int *)buf;
GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
bufptr += GLUE_MOV_PX_DIRECTVALUE_SIZE/4;
*bufptr++ = 0xD8230000; // stfd f1, 0(r3)
}
return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int);
}
#define GLUE_POP_FPSTACK_SIZE 0
static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack
static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = {
0xdc21fff0, // stfdu f1, -16(r1)
};
static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = {
0xdc300008, // stfdu f1, 8(r16)
};
#define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
{
static const unsigned int tab[3] = {
0xC8230000, // lfd f1, 0(r3)
0xC82E0000, // lfd f1, 0(r14)
0xC82F0000, // lfd f1, 0(r15)
};
*(unsigned int *)b = tab[wv];
}
#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE)
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
{
memcpy(buf,GLUE_POP_FPSTACK_TO_WTP,sizeof(GLUE_POP_FPSTACK_TO_WTP));
GLUE_SET_PX_FROM_WTP(buf + sizeof(GLUE_POP_FPSTACK_TO_WTP),wv); // ppc preincs the WTP, so we do this after
};
static unsigned int GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo
static const unsigned int GLUE_SET_P1_Z[] = { 0x38600000 }; // li r3, 0
static const unsigned int GLUE_SET_P1_NZ[] = { 0x38600001 }; // li r3, 1
static void *GLUE_realAddress(void *fn, int *size)
{
// magic numbers: mr r0,r0 ; mr r1,r1 ; mr r2, r2
static const unsigned char sig[12] = { 0x7c, 0x00, 0x03, 0x78, 0x7c, 0x21, 0x0b, 0x78, 0x7c, 0x42, 0x13, 0x78 };
unsigned char *p = (unsigned char *)fn;
while (memcmp(p,sig,sizeof(sig))) p+=4;
p+=sizeof(sig);
fn = p;
while (memcmp(p,sig,sizeof(sig))) p+=4;
*size = p - (unsigned char *)fn;
return fn;
}
#define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(x) 4
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
{
// limited to 32k offset
*(unsigned int *)b = 0x90610000 + (offs&0xffff);
}
#define GLUE_MOVE_PX_STACKPTR_SIZE 4
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
{
static const unsigned int tab[3] =
{
0x7c230b78, // mr r3, r1
0x7c2e0b78, // mr r14, r1
0x7c2f0b78, // mr r15, r1
};
* (unsigned int *)b = tab[wv];
}
#define GLUE_MOVE_STACK_SIZE 4
static void GLUE_MOVE_STACK(void *b, int amt)
{
// this should be updated to allow for more than 32k moves, but no real need
((unsigned int *)b)[0] = 0x38210000 + (amt&0xffff); // addi r1,r1, amt
}
// end of ppc
#endif