Skip to content

Instantly share code, notes, and snippets.

@classilla
Created January 7, 2020 05:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save classilla/ac2458ce7ab27f93b22ff32b9fa10d09 to your computer and use it in GitHub Desktop.
Save classilla/ac2458ce7ab27f93b22ff32b9fa10d09 to your computer and use it in GitHub Desktop.
Simple ppc64/ppc64le generated machine code example that's a little more complicated
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <linux/memfd.h>
uint32_t* jitcode;
uint32_t* jitcode_x;
int (*calljit)(int);
// op comes right out of the PowerISA 3.0 documentation
#define IMM(op, regsd, rega, imm) (uint32_t)(((op)<<26)|((regsd)<<21)|((rega)<<16)| (((imm))&0xFFFF))
#define DSF(op, regs, rega, ds, bb) (uint32_t)(((op)<<26)|((regs) <<21)|((rega)<<16)| (((ds))&0xFFFC)|(bb))
#define EXT(regsd, rega, regb, op, rc) (uint32_t)( (31<<26)|((regsd)<<21)|((rega)<<16)| ((regb)<<11)| ((op)<<1) |(rc))
#define RLW(op, regs, rega, sh, mb, me, rc) (uint32_t)(((op)<<26)|((regs) <<21)|((rega)<<16)| ((sh)<<11)|((mb )<<6)|((me)<<1) |(rc))
#define RLD(op, regs, rega, sh, mx, opb, rc) (uint32_t)(((op)<<26)|((regs) <<21)|((rega)<<16)|((sh&31)<<11)|((mx&31)<<6)|(mx&32) |((opb)<<2)|((sh&32)>>4)|(rc))
static int printint(int x) { fprintf(stdout, "called with %d\n", x); return x; }
int main(int argc, char** argv) {
int fd, rv = 0;
size_t pagesize;
uint64_t f;
pagesize = sysconf(_SC_PAGE_SIZE);
fd = syscall(__NR_memfd_create, "jitlab", MFD_CLOEXEC);
ftruncate(fd, pagesize);
jitcode = (uint32_t*)mmap(NULL, pagesize,
PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
f = (uint64_t)&printint;
jitcode[0] = DSF(62, 1, 1, -256, 1); // stdu 1,-256(1)
jitcode[1] = EXT(0, 8, 0, 339, 0); // mflr 0
jitcode[2] = IMM(15, 12, 0, (f & 0xffff000000000000)>>48); // lis
jitcode[3] = IMM(24, 12, 12, (f & 0x0000ffff00000000)>>32); // ori
jitcode[4] = RLD(30, 12, 12, 32, 31, 1, 0); // rldicr 12,12,32,31
jitcode[5] = IMM(25, 12, 12, (f & 0x00000000ffff0000)>>16); // oris
jitcode[6] = IMM(24, 12, 12, (f & 0x000000000000ffff) ); // ori
jitcode[7] = EXT(12, 9, 0, 467, 0); // mtctr 12
jitcode[8] = IMM(14, 3, 3, 2020); // addi 3, 3, 2020
jitcode[9] = DSF(62, 0, 1, 272, 0); // std 0,272(1)
jitcode[10] = IMM(19, 20, 0, (528<<1)|1); // bctrl
jitcode[11] = DSF(58, 0, 1, 272, 0); // ld 0,272(1)
jitcode[12] = EXT(0, 8, 0, 467, 0); // mtlr 0
jitcode[13] = EXT(3, 3, 3, 266, 0); // add 3,3,3
jitcode[14] = IMM(14, 1, 1, 256); // addi 1,1,256
jitcode[15] = IMM(19, 20, 0, 32); // blr
fprintf(stdout, "jitcode at 0x%llx\n", (uint64_t)jitcode);
asm volatile(
"dcbst %y0\n"
"sync\n"
"icbi %y0\n"
"isync\n"
:: "Z"(*jitcode));
jitcode_x = (uint32_t*)mmap(NULL, pagesize,
PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
calljit = (int (*)(int))jitcode_x;
rv = calljit(1111);
fprintf(stdout, "result = %d\n", rv);
munmap(jitcode, pagesize);
munmap(jitcode_x, pagesize);
close(fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment