mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2024-12-22 10:29:53 +00:00
LD/LDU/SD (64-bits, dual regs) support in Vex + accel ; ramdisk tested in Q650
This commit is contained in:
parent
2d2cbdbafe
commit
173c87ea02
1
nubus-to-ztex-gateware/.gitignore
vendored
1
nubus-to-ztex-gateware/.gitignore
vendored
@ -11,3 +11,4 @@ blit.raw
|
||||
blit.s
|
||||
*.patch
|
||||
OLD
|
||||
nubusfpga_csr_*.h
|
||||
|
7
nubus-to-ztex-gateware/DeclROM/.gitignore
vendored
Normal file
7
nubus-to-ztex-gateware/DeclROM/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
vid_decl_rom.bin
|
||||
vid_decl_rom.dir
|
||||
vid_decl_rom.l
|
||||
vid_decl_rom.o
|
||||
vid_decl_rom.raw
|
||||
vid_decl_rom.srec
|
||||
*.bin
|
@ -93,6 +93,7 @@ vid_decl_rom.dir: vid_decl_rom.raw append_romdir
|
||||
|
||||
vid_decl_rom.bin: vid_decl_rom.dir
|
||||
${NUBUS_CHECKSUM} --input_file $< --output_file $@ --output_size 32768
|
||||
dd if=dump.cpr of=vid_decl_rom.bin bs=1 conv=notrunc
|
||||
|
||||
clean:
|
||||
rm -f res.inc ${CSRC_ASM} *.o vid_decl_rom.srec vid_decl_rom.raw vid_decl_rom.dir vid_decl_rom.l
|
||||
|
@ -18,6 +18,8 @@
|
||||
#endif
|
||||
|
||||
#define GOBOFB_BASE 0x00900000
|
||||
#define GOBOFB_ACCEL 0x00901000
|
||||
#define GOBOFB_ACCEL_LE 0x00901800
|
||||
|
||||
//#define GOBOFB_REG_BASE 0x00900000
|
||||
//#define GOBOFB_MEM_BASE 0x00000000 /* remapped to 0x8f800000 by HW */
|
||||
@ -44,6 +46,34 @@
|
||||
#define GOBOFB_MODE_24BIT 0x10
|
||||
#define GOBOFB_MODE_15BIT 0x11
|
||||
|
||||
#define u_int32_t volatile unsigned long
|
||||
struct goblin_accel_regs {
|
||||
u_int32_t reg_status; // 0
|
||||
u_int32_t reg_cmd;
|
||||
u_int32_t reg_r5_cmd;
|
||||
u_int32_t resv0;
|
||||
u_int32_t reg_width; // 4
|
||||
u_int32_t reg_height;
|
||||
u_int32_t reg_fgcolor;
|
||||
u_int32_t resv2;
|
||||
u_int32_t reg_bitblt_src_x; // 8
|
||||
u_int32_t reg_bitblt_src_y;
|
||||
u_int32_t reg_bitblt_dst_x;
|
||||
u_int32_t reg_bitblt_dst_y;
|
||||
u_int32_t reg_src_stride; // 12
|
||||
u_int32_t reg_dst_stride;
|
||||
u_int32_t reg_src_ptr; // 12
|
||||
u_int32_t reg_dst_ptr;
|
||||
};
|
||||
|
||||
// status
|
||||
#define WORK_IN_PROGRESS_BIT 0
|
||||
|
||||
// cmd
|
||||
#define DO_BLIT_BIT 0 // hardwired in goblin_accel.py
|
||||
#define DO_FILL_BIT 1 // hardwired in goblin_accel.py
|
||||
#define DO_TEST_BIT 3 // hardwired in goblin_accel.py
|
||||
|
||||
struct MyGammaTbl {
|
||||
short gVersion; /*gamma version number*/
|
||||
short gType; /*gamma data type*/
|
||||
|
@ -276,10 +276,12 @@ OSErr cNuBusFPGACtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
||||
UInt32 a32_4p0, a32_4p1;
|
||||
const uint32_t wb = HRES >> idx;
|
||||
unsigned short j, i;
|
||||
|
||||
if (vPInfo->csPage != 0)
|
||||
return paramErr;
|
||||
|
||||
SwapMMUMode ( &busMode );
|
||||
#if 0
|
||||
if ((dStore->curMode != kDepthMode5) && (dStore->curMode != kDepthMode6)) {
|
||||
/* grey the screen */
|
||||
a32_l0 = a32;
|
||||
@ -313,6 +315,25 @@ OSErr cNuBusFPGACtl(CntrlParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
||||
a32_l1 += 2*HRES*4;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#define WAIT_FOR_HW_LE(accel_le) \
|
||||
while (accel_le->reg_status & (1<<WORK_IN_PROGRESS_BIT))
|
||||
const UInt32 fgcolor = 0; // FIXME: per-depth?
|
||||
struct goblin_accel_regs* accel_le = (struct goblin_accel_regs*)(dce->dCtlDevBase+GOBOFB_ACCEL_LE);
|
||||
WAIT_FOR_HW_LE(accel_le);
|
||||
accel_le->reg_width = HRES; // pixels
|
||||
accel_le->reg_height = VRES;
|
||||
accel_le->reg_bitblt_dst_x = 0; // pixels
|
||||
accel_le->reg_bitblt_dst_y = 0;
|
||||
accel_le->reg_dst_ptr = 0;
|
||||
accel_le->reg_fgcolor = fgcolor;
|
||||
accel_le->reg_cmd = (1<<DO_FILL_BIT);
|
||||
WAIT_FOR_HW_LE(accel_le);
|
||||
|
||||
#undef WAIT_FOR_HW_LE
|
||||
|
||||
#endif
|
||||
SwapMMUMode ( &busMode );
|
||||
|
||||
ret = noErr;
|
||||
|
@ -24,6 +24,7 @@ UInt32 Primary(SEBlock* seblock) {
|
||||
/* PRIM_WRITEREG(GOBOFB_DEBUG, busMode);// trace */
|
||||
|
||||
/* grey the screen */
|
||||
/* should switch to HW ? */
|
||||
a32_l0 = a32;
|
||||
a32_l1 = a32 + HRES;
|
||||
for (j = 0 ; j < VRES ; j+= 2) {
|
||||
|
@ -12,11 +12,6 @@
|
||||
|
||||
struct RAMDrvContext {
|
||||
DrvSts2 drvsts;
|
||||
//Ptr origcopyfunc;
|
||||
//Ptr origdisk; /* keep unstripped pointers for Dispose*/
|
||||
//unsigned char * disk;
|
||||
//char initialized;
|
||||
//char alreadyalloced;
|
||||
};
|
||||
|
||||
#define DRIVE_SIZE_BYTES ((256ul-8ul)*1024ul*1024ul) // FIXME: mem size minus fb size
|
||||
|
@ -6,22 +6,27 @@
|
||||
OSErr cNuBusFPGARAMDskOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
||||
{
|
||||
DrvSts2 *dsptr; // pointer to the DrvSts2 in our context
|
||||
DrvQElPtr dq;
|
||||
int drvnum = 1;
|
||||
struct RAMDrvContext *ctx;
|
||||
OSErr ret = noErr;
|
||||
char busMode;
|
||||
|
||||
dce->dCtlDevBase = 0xfc000000;
|
||||
busMode = 1;
|
||||
SwapMMUMode ( &busMode ); // to32 // this likely won't work on older MacII ???
|
||||
|
||||
dce->dCtlDevBase = 0xfc000000; // FIXME: why do we not get our slot properly ?
|
||||
|
||||
write_reg(dce, GOBOFB_DEBUG, 0xDEAD0000);
|
||||
/* write_reg(dce, GOBOFB_DEBUG, dce->dCtlRefNum); */
|
||||
|
||||
if (dce->dCtlStorage == nil) {
|
||||
DrvQElPtr dq;
|
||||
for(dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) {
|
||||
if (dq->dQDrive >= drvnum)
|
||||
drvnum = dq->dQDrive+1;
|
||||
}
|
||||
|
||||
ReserveMemSys(sizeof(struct RAMDrvContext));
|
||||
dce->dCtlStorage = NewHandleSysClear(sizeof(struct RAMDrvContext));
|
||||
if (dce->dCtlStorage == nil) {
|
||||
ret = openErr;
|
||||
@ -65,7 +70,7 @@ OSErr cNuBusFPGARAMDskOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
||||
write_reg(dce, GOBOFB_DEBUG, compressed[2]);
|
||||
write_reg(dce, GOBOFB_DEBUG, compressed[3]);
|
||||
*/
|
||||
res = rledec(superslot, compressed, 730);
|
||||
res = rledec(superslot, compressed, 730); // FIXME: 730 = 2920/4 (compressed size in words)
|
||||
/*
|
||||
write_reg(dce, GOBOFB_DEBUG, res);
|
||||
write_reg(dce, GOBOFB_DEBUG, 0xDEEEEEAD);
|
||||
@ -76,6 +81,7 @@ OSErr cNuBusFPGARAMDskOpen(IOParamPtr pb, /* DCtlPtr */ AuxDCEPtr dce)
|
||||
MyAddDrive(dsptr->dQRefNum, drvnum, (DrvQElPtr)&dsptr->qLink);
|
||||
}
|
||||
|
||||
SwapMMUMode ( &busMode );
|
||||
|
||||
done:
|
||||
return ret;
|
||||
|
@ -60,15 +60,20 @@ uint32_t rledec(uint32_t* out, const uint32_t* in, const uint32_t len) {
|
||||
#endif
|
||||
if (c >= 0) {
|
||||
chk += (1 + c);
|
||||
if (c < 10000) // !!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
for (k = 0 ; k < c+1 ; k++)
|
||||
if (c < 300000) { // !!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
for (k = 0 ; k < (c + 1) ; k++)
|
||||
out[j++] = in[i+1];
|
||||
else
|
||||
} else { // do a small subset at the beginning and end instead of the full range and assume this is padding otherwise
|
||||
for (k = 0 ; k < 4 ; k++)
|
||||
out[j+k] = in[i+1];
|
||||
for (k = c-3 ; k < (c + 1) ; k++)
|
||||
out[j+k] = in[i+1];
|
||||
j += c+1;
|
||||
}
|
||||
i += 2;
|
||||
} else {
|
||||
chk += 1 + -c;
|
||||
for (k = 0 ; k < 1 + -c ; k++)
|
||||
chk += (1 + -c);
|
||||
for (k = 0 ; k < (1 + -c) ; k++)
|
||||
out[j++] = in[i+1+k];
|
||||
i += 2 + -c;
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ object GenGoblinAccel { // extends App {
|
||||
val config = VexRiscvConfig(
|
||||
plugins = List(
|
||||
new IBusCachedPlugin(
|
||||
resetVector = 0x70910000, // beginning of ROM
|
||||
resetVector = 0xF0910000l, // beginning of ROM
|
||||
relaxedPcCalculation = false,
|
||||
prediction = STATIC,
|
||||
config = InstructionCacheConfig(
|
||||
cacheSize = 512,
|
||||
bytePerLine = 32,
|
||||
cacheSize = 256,
|
||||
bytePerLine = 16,
|
||||
wayCount = 1,
|
||||
addressWidth = 32,
|
||||
cpuDataWidth = 32,
|
||||
@ -42,8 +42,8 @@ object GenGoblinAccel { // extends App {
|
||||
// ),
|
||||
new DBusCachedPlugin(
|
||||
config = new DataCacheConfig(
|
||||
cacheSize = 512,
|
||||
bytePerLine = 32,
|
||||
cacheSize = 256,
|
||||
bytePerLine = 16,
|
||||
wayCount = 2,
|
||||
addressWidth = 32,
|
||||
cpuDataWidth = 128,
|
||||
@ -51,7 +51,7 @@ object GenGoblinAccel { // extends App {
|
||||
catchAccessError = false,
|
||||
catchIllegal = false,
|
||||
catchUnaligned = false,
|
||||
pendingMax = 8, // 64
|
||||
pendingMax = 8, // 64 ; irrelevant? only for SMP?
|
||||
withWriteAggregation = true // required if memDataWidth > 32
|
||||
),
|
||||
dBusCmdMasterPipe = false, // prohibited if memDataWidth > 32
|
||||
@ -68,8 +68,8 @@ object GenGoblinAccel { // extends App {
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = false
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = plugin.SYNC,
|
||||
new RegFileOddEvenPlugin(
|
||||
regFileReadyKind = plugin.ASYNC, // FIXME why is even-odd failing with SYNC??? (and what's the difference...)
|
||||
zeroBoot = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
@ -83,7 +83,7 @@ object GenGoblinAccel { // extends App {
|
||||
//new BitManipZbaPlugin(earlyInjection = false), // sh.add
|
||||
//new BitManipZbbPlugin(earlyInjection = false), // zero-ext, min/max, others
|
||||
//new BitManipZbtPlugin(earlyInjection = false), // cmov, cmix, funnel
|
||||
new CG6Plugin(earlyInjection = false),
|
||||
new CG6Plugin(earlyInjection = false), // full-custom list
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = true,
|
||||
bypassMemory = true,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -81,6 +81,8 @@ struct goblin_accel_regs {
|
||||
|
||||
//#include "./rvintrin.h"
|
||||
|
||||
#include "ldsdsupport.h"
|
||||
|
||||
void from_reset(void) __attribute__ ((noreturn)); // nothrow,
|
||||
|
||||
static inline void flush_cache(void) {
|
||||
@ -376,6 +378,17 @@ static void rectfill(const unsigned_param_type xd,
|
||||
}
|
||||
if (wi > 3) {
|
||||
unsigned int u32color = (unsigned int)u8color | ((unsigned int)u8color)<<8 | ((unsigned int)u8color)<<16 | ((unsigned int)u8color)<<24;
|
||||
if ((wi>15) && (((unsigned int)dptr_elt&0x7)==0)) {
|
||||
register unsigned int s8 asm("s8");
|
||||
register unsigned int s9 asm("s9");
|
||||
s8 = u32color;
|
||||
s9 = u32color;
|
||||
for ( ; i < (wi-15) ; i+=16) {
|
||||
sd(dptr_elt, 0, 0, s8, s9);
|
||||
sd(dptr_elt, 8, 0, s8, s9);
|
||||
dptr_elt += 16;
|
||||
}
|
||||
}
|
||||
for ( ; i < (wi-3) ; i+=4) {
|
||||
*(unsigned int*)dptr_elt = u32color;
|
||||
dptr_elt +=4;
|
||||
@ -733,9 +746,138 @@ static void invert(const unsigned_param_type xd,
|
||||
BLIT_FWD_BWD(NAME, OP) \
|
||||
BLIT_BWD_FWD(NAME, OP) \
|
||||
|
||||
#define BLIT_NOTALLDIR(NAME, OP) \
|
||||
BLIT_FWD_BWD(NAME, OP) \
|
||||
BLIT_BWD_FWD(NAME, OP) \
|
||||
|
||||
BLIT_ALLDIR(copy, COPY)
|
||||
//BLIT_ALLDIR(copy, COPY)
|
||||
BLIT_NOTALLDIR(copy, COPY)
|
||||
BLIT_ALLDIR(xor, XOR)
|
||||
BLIT_ALLDIR(copy_pm, COPY_PM)
|
||||
BLIT_ALLDIR(xor_pm, XOR_PM)
|
||||
|
||||
|
||||
static void bitblit_fwd_fwd_copy(const unsigned_param_type xs,
|
||||
const unsigned_param_type ys,
|
||||
const unsigned_param_type wi,
|
||||
const unsigned_param_type re,
|
||||
const unsigned_param_type xd,
|
||||
const unsigned_param_type yd,
|
||||
const unsigned char pm,
|
||||
unsigned char* src_ptr,
|
||||
unsigned char* dst_ptr,
|
||||
const unsigned_param_type src_stride,
|
||||
const unsigned_param_type dst_stride) {
|
||||
unsigned int j;
|
||||
unsigned char *sptr = (src_ptr + (ys * src_stride) + xs);
|
||||
unsigned char *dptr = (dst_ptr + (yd * dst_stride) + xd);
|
||||
unsigned char *sptr_line = sptr;
|
||||
unsigned char *dptr_line = dptr;
|
||||
/*const unsigned char npm = ~pm;*/
|
||||
|
||||
for (j = 0 ; j < re ; j++) {
|
||||
register unsigned char *sptr_elt = sptr_line;
|
||||
unsigned char *dptr_elt = dptr_line;
|
||||
const unsigned char *dptr_elt_last = dptr_line + wi;
|
||||
if (wi>3) {
|
||||
if ((xs & 0x3) != (xd & 0x3)) {
|
||||
/* align dest, we'll deal with src via shift realignement using fsr */
|
||||
for ( ; (dptr_elt < dptr_elt_last) && ((unsigned int)dptr_elt&0x3)!=0; ) {
|
||||
dptr_elt[0] = sptr_elt[0];
|
||||
dptr_elt ++;
|
||||
sptr_elt ++;
|
||||
}
|
||||
unsigned char *sptr_elt_al = (unsigned char*)((unsigned int)sptr_elt & ~0x3);
|
||||
unsigned int fsr_cst = 8*((unsigned int)sptr_elt & 0x3);
|
||||
unsigned int src0 = ((unsigned int*)sptr_elt_al)[0];
|
||||
unsigned int u32pm = (unsigned int)pm | ((unsigned int)pm)<<8 | ((unsigned int)pm)<<16 | ((unsigned int)pm)<<24;
|
||||
/* handle unaligned src */
|
||||
for ( ; (dptr_elt < (dptr_elt_last-3)) ; ) {
|
||||
unsigned int src1 = ((unsigned int*)sptr_elt_al)[1];
|
||||
unsigned int val;
|
||||
asm("fsr %0, %1, %2, %3\n" : "=r"(val) : "r"(src0), "r"(src1), "r"(fsr_cst));
|
||||
((unsigned int*)dptr_elt)[0] = val;
|
||||
src0 = src1;
|
||||
dptr_elt += 4;
|
||||
sptr_elt_al += 4;
|
||||
}
|
||||
sptr_elt = sptr_elt_al + ((unsigned int)sptr_elt & 0x3);
|
||||
} else {
|
||||
const unsigned int u32pm = (unsigned int)pm | ((unsigned int)pm)<<8 | ((unsigned int)pm)<<16 | ((unsigned int)pm)<<24;
|
||||
const unsigned char* dptr_elt_end = dptr_elt + wi;
|
||||
/* align dest & src (they are aligned the same here) */
|
||||
for ( ; (dptr_elt < dptr_elt_last) && ((unsigned int)dptr_elt&0x3)!=0; ) {
|
||||
dptr_elt[0] = sptr_elt[0];
|
||||
dptr_elt ++;
|
||||
sptr_elt ++;
|
||||
}
|
||||
/* align to 8 for ls/sd */
|
||||
for ( ; (dptr_elt < (dptr_elt_last-3)) && ((unsigned int)dptr_elt&0x7)!=0;) {
|
||||
((unsigned int*)dptr_elt)[0] = ((unsigned int*)sptr_elt)[0];
|
||||
dptr_elt += 4;
|
||||
sptr_elt += 4;
|
||||
}
|
||||
#if 0
|
||||
for ( ; (dptr_elt < (dptr_elt_last-31)) ; ) {
|
||||
register unsigned int s4 asm("s4");
|
||||
register unsigned int s5 asm("s5");
|
||||
register unsigned int s6 asm("s6");
|
||||
register unsigned int s7 asm("s7");
|
||||
register unsigned int s8 asm("s8");
|
||||
register unsigned int s9 asm("s9");
|
||||
register unsigned int s10 asm("s10");
|
||||
register unsigned int s11 asm("s11");
|
||||
ld(sptr_elt, 0, s4, s5);
|
||||
ld(sptr_elt, 16, s8, s9);
|
||||
|
||||
ld(sptr_elt, 8, s6, s7);
|
||||
sd(dptr_elt, 0, 0, s4, s5);
|
||||
sd(dptr_elt, 8, 0, s6, s7);
|
||||
|
||||
ld(sptr_elt, 24, s10, s11);
|
||||
sd(dptr_elt, 16, 0, s8, s9);
|
||||
sptr_elt += 32;
|
||||
sd(dptr_elt, 24, 0, s10, s11);
|
||||
dptr_elt += 32;
|
||||
|
||||
}
|
||||
#endif
|
||||
for ( ; (dptr_elt < (dptr_elt_last-15)) ; ) {
|
||||
register unsigned int s8 asm("s8");
|
||||
register unsigned int s9 asm("s9");
|
||||
register unsigned int s10 asm("s10");
|
||||
register unsigned int s11 asm("s11");
|
||||
ld(sptr_elt, 0, s8, s9);
|
||||
ld(sptr_elt, 8, s10, s11);
|
||||
sd(dptr_elt, 0, 0, s8, s9);
|
||||
sptr_elt += 16;
|
||||
sd(dptr_elt, 8, 0, s10, s11);
|
||||
dptr_elt += 16;
|
||||
}
|
||||
#if 0
|
||||
for ( ; (dptr_elt < (dptr_elt_last-7)) ; ) {
|
||||
register unsigned int s8 asm("s8");
|
||||
register unsigned int s9 asm("s9");
|
||||
ld(sptr_elt, 0, s8, s9);
|
||||
sd(dptr_elt, 0, 0, s8, s9);
|
||||
sptr_elt += 8;
|
||||
dptr_elt += 8;
|
||||
}
|
||||
#endif
|
||||
for ( ; (dptr_elt < (dptr_elt_last-3)) ; ) {
|
||||
((unsigned int*)dptr_elt)[0] = ((unsigned int*)sptr_elt)[0];
|
||||
dptr_elt += 4;
|
||||
sptr_elt += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* common tail loop */
|
||||
for ( ; dptr_elt < dptr_elt_last ; ) {
|
||||
dptr_elt[0] = sptr_elt[0];
|
||||
dptr_elt ++;
|
||||
sptr_elt ++;
|
||||
}
|
||||
sptr_line += src_stride;
|
||||
dptr_line += dst_stride;
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ GCCPFX=riscv32-buildroot-linux-gnu-
|
||||
GCC=${GCCDIR}/bin/${GCCPFX}gcc
|
||||
OBJCOPY=${GCCDIR}/bin/${GCCPFX}objcopy
|
||||
|
||||
OPT=-Os #-fno-inline
|
||||
OPT=-O3 #-fno-inline
|
||||
ARCH=rv32im_zba_zbb_zbt
|
||||
|
||||
PARAM="-DBASE_FB=${BASE_FB}"
|
||||
|
84
nubus-to-ztex-gateware/ldsdsupport.h
Normal file
84
nubus-to-ztex-gateware/ldsdsupport.h
Normal file
@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
asm(".set regnum_x0 , 0");
|
||||
asm(".set regnum_x1 , 1");
|
||||
asm(".set regnum_x2 , 2");
|
||||
asm(".set regnum_x3 , 3");
|
||||
asm(".set regnum_x4 , 4");
|
||||
asm(".set regnum_x5 , 5");
|
||||
asm(".set regnum_x6 , 6");
|
||||
asm(".set regnum_x7 , 7");
|
||||
asm(".set regnum_x8 , 8");
|
||||
asm(".set regnum_x9 , 9");
|
||||
asm(".set regnum_x10 , 10");
|
||||
asm(".set regnum_x11 , 11");
|
||||
asm(".set regnum_x12 , 12");
|
||||
asm(".set regnum_x13 , 13");
|
||||
asm(".set regnum_x14 , 14");
|
||||
asm(".set regnum_x15 , 15");
|
||||
asm(".set regnum_x16 , 16");
|
||||
asm(".set regnum_x17 , 17");
|
||||
asm(".set regnum_x18 , 18");
|
||||
asm(".set regnum_x19 , 19");
|
||||
asm(".set regnum_x20 , 20");
|
||||
asm(".set regnum_x21 , 21");
|
||||
asm(".set regnum_x22 , 22");
|
||||
asm(".set regnum_x23 , 23");
|
||||
asm(".set regnum_x24 , 24");
|
||||
asm(".set regnum_x25 , 25");
|
||||
asm(".set regnum_x26 , 26");
|
||||
asm(".set regnum_x27 , 27");
|
||||
asm(".set regnum_x28 , 28");
|
||||
asm(".set regnum_x29 , 29");
|
||||
asm(".set regnum_x30 , 30");
|
||||
asm(".set regnum_x31 , 31");
|
||||
|
||||
asm(".set regnum_zero, 0");
|
||||
asm(".set regnum_ra , 1");
|
||||
asm(".set regnum_sp , 2");
|
||||
asm(".set regnum_gp , 3");
|
||||
asm(".set regnum_tp , 4");
|
||||
asm(".set regnum_t0 , 5");
|
||||
asm(".set regnum_t1 , 6");
|
||||
asm(".set regnum_t2 , 7");
|
||||
asm(".set regnum_s0 , 8");
|
||||
asm(".set regnum_s1 , 9");
|
||||
asm(".set regnum_a0 , 10");
|
||||
asm(".set regnum_a1 , 11");
|
||||
asm(".set regnum_a2 , 12");
|
||||
asm(".set regnum_a3 , 13");
|
||||
asm(".set regnum_a4 , 14");
|
||||
asm(".set regnum_a5 , 15");
|
||||
asm(".set regnum_a6 , 16");
|
||||
asm(".set regnum_a7 , 17");
|
||||
asm(".set regnum_s2 , 18");
|
||||
asm(".set regnum_s3 , 19");
|
||||
asm(".set regnum_s4 , 20");
|
||||
asm(".set regnum_s5 , 21");
|
||||
asm(".set regnum_s6 , 22");
|
||||
asm(".set regnum_s7 , 23");
|
||||
asm(".set regnum_s8 , 24");
|
||||
asm(".set regnum_s9 , 25");
|
||||
asm(".set regnum_s10 , 26");
|
||||
asm(".set regnum_s11 , 27");
|
||||
asm(".set regnum_t3 , 28");
|
||||
asm(".set regnum_t4 , 29");
|
||||
asm(".set regnum_t5 , 30");
|
||||
asm(".set regnum_t6 , 31");
|
||||
|
||||
#define opcode_ld(opcode, func3, base, imm12, o1, o2) \
|
||||
asm volatile(".word ((" #opcode ") | (regnum_%0 << 7) | (regnum_%2 << 15) | (" #imm12 " << 20) | ((" #func3 ") << 12));" \
|
||||
: "=&r" (o1), "=&r" (o2) \
|
||||
: "r" (base) \
|
||||
); \
|
||||
|
||||
#define ld(base, imm12, o1, o2) opcode_ld(0x03, 0x03, base, imm12, o1, o2)
|
||||
#define ldu(base, imm12, o1, o2) opcode_ld(0x03, 0x07, base, imm12, o1, o2)
|
||||
|
||||
#define opcode_sd(opcode, func3, base, imm04, imm511, i1, i2) \
|
||||
asm volatile(".word ((" #opcode ") | (" #imm04 " << 7) | (regnum_%0 << 15) | (regnum_%1 << 20) | (" #imm511 " << 25) | ((" #func3 ") << 12));" \
|
||||
: \
|
||||
: "r" (base), "r" (i1), "r" (i2) \
|
||||
); \
|
||||
|
||||
#define sd(base, imm04, imm511, i1, i2) opcode_sd(0x23, 0x03, base, imm04, imm511, i1, i2)
|
Loading…
Reference in New Issue
Block a user