LADSoft / OrangeC

OrangeC Compiler And Tool Chain
http://ladsoft.tripod.com/orange_c_compiler.html
Other
296 stars 39 forks source link

PPC-64 bit assembler #493

Open LADSoft opened 4 years ago

LADSoft commented 4 years ago

write the assembler/compiler backend for PPC-64 bit

bencz commented 4 years ago

@LADSoft Here a small C code of how the ppc instructions are encoded:

#include <stdio.h>

#define WORD_SIZE 32

typedef unsigned int u32;
u32 opHex = 0;

void printInstruction(const char* desc, int val)
{
    printf("%-25s = ", desc);
    printf("%02X ", (val >> 24) & 0xFF);
    printf("%02X ", (val >> 16) & 0xFF);
    printf("%02X ", (val >> 8)  & 0xFF);
    printf("%02X ", (val)       & 0xFF);
    printf("\n");
}

int getShiftNum(int endPos)
{
    return (WORD_SIZE - 1 - endPos);
}

int getOpSegment(int val, int size, int pos)
{
    int mask = (1 << size) - 1;
    val &= mask;
    val <<= getShiftNum(pos);
    return val;
}

void STW(const char* desc, int destReg, int addressReg, int immediate)
{
    // STW opcode = 0x24

    opHex = getOpSegment(0x24, 6, 5);
    opHex |= getOpSegment(destReg, 5, 10);
    opHex |= getOpSegment(addressReg, 5, 15);
    opHex |= getOpSegment(immediate, 16, 31);
    printInstruction(desc, opHex);
}

void STWU(const char* desc, int destReg, int addressReg, int immediate)
{
    // STW opcode = 0x25

    opHex = getOpSegment(0x25, 6, 5);
    opHex |= getOpSegment(destReg, 5, 10);
    opHex |= getOpSegment(addressReg, 5, 15);
    opHex |= getOpSegment(immediate, 16, 31);
    printInstruction(desc, opHex);
}

void OR(const char* desc, int destReg, int sourceReg1, int sourceReg2)
{
    // OR opcode = 0x1F

    opHex = getOpSegment(0x1F, 6, 5);
    opHex |= getOpSegment(sourceReg1, 5, 10);
    opHex |= getOpSegment(destReg, 5, 15);
    opHex |= getOpSegment(sourceReg2, 5, 20);
    opHex |= getOpSegment(444, 10, 30);
    printInstruction(desc, opHex);
}

int main()
{
    STWU("stwu\tr1,  -0x20(r1)", 0x00000001, 0x00000001, -0x20);
    STW("stw \tr31, +0x4(r1)", 0x0000001F, 0x00000001, 28);
    OR("or  \tr31, r1, r1", 31, 1, 1);
    STW("stw \tr31, +0x18(r31)", 0x00000003, 0x0000001F, 8);
    STW("stw \tr31, +0x14(r31)", 0x00000004, 0x0000001F, 12);
    STW("stw \tr31, +0x10(r31)", 0x00000005, 0x0000001F, 16);
    STW("stw \tr31, +0xC0(r31)", 0x00000006, 0x0000001F, 20);

    return 0;
}
bencz commented 4 years ago

You can look to this project too ( really simple but interesting project ): https://github.com/Fracture17/PowerPC-Assembly-Functions

LADSoft commented 4 years ago

cool that looks pretty easy. My adl file format should handle it well enough...