# Syntax: # : a field occupying so many bits. # T: a field occupying one bit. # .: a bit we don't care about. # Branch processor instructions. <18-->AL branch(0x1f, 0x00, ext26(LI<<2), A, L); <16-->AL branch(BO, BI, ext16(BD<<2), A, L); <19--><16------>L branch(BO, BI, cpu.lr, 1, L); <19--><528----->L branch(BO, BI, cpu.ctr, 1, L); <17-->.................1. system_call(LEV); # Condition register instructions. <19--><257----->. setcr(BT, getcr(BA) & getcr(BB)); <19--><449----->. setcr(BT, getcr(BA) | getcr(BB)); <19--><193----->. setcr(BT, getcr(BA) ^ getcr(BB)); <19--><225----->. setcr(BT, !(getcr(BA) & getcr(BB))); <19--><33------>. setcr(BT, !(getcr(BA) | getcr(BB))); <19--><289----->. setcr(BT, getcr(BA) == getcr(BB)); <19--><129----->. setcr(BT, getcr(BA) & !getcr(BB)); <19--><417----->. setcr(BT, getcr(BA) | !getcr(BB)); <19-->.......<0------->. mcrf(BF, BA); # Fixed point loads <34--> cpu.gpr[RT] = read_byte(reg0(RA) + ext16(D)); <31--><87------>. cpu.gpr[RT] = read_byte(reg0(RA) + reg(RB)); <35--> uint32_t ea = reg(RA) + ext16(D); cpu.gpr[RT] = read_byte(ea); cpu.gpr[RA] = ea; <31--><119----->. uint32_t ea = reg(RA) + reg(RB); cpu.gpr[RT] = read_byte(ea); cpu.gpr[RA] = ea; <40--> cpu.gpr[RT] = read_word(reg0(RA) + ext16(D)); <31--><279----->. cpu.gpr[RT] = read_word(reg0(RA) + reg(RB)); <41--> uint32_t ea = reg(RA) + ext16(D); cpu.gpr[RT] = read_word(ea); cpu.gpr[RA] = ea; <31--><311----->. uint32_t ea = reg(RA) + reg(RB); cpu.gpr[RT] = read_word(ea); cpu.gpr[RA] = ea; <42--> cpu.gpr[RT] = ext16(read_word(reg0(RA) + ext16(D))); <31--><343----->. cpu.gpr[RT] = ext16(read_word(reg0(RA) + reg(RB))); <43--> uint32_t ea = reg(RA) + ext16(D); cpu.gpr[RT] = ext16(read_word(ea)); cpu.gpr[RA] = ea; <31--><375----->. uint32_t ea = reg(RA) + reg(RB); cpu.gpr[RT] = ext16(read_word(ea)); cpu.gpr[RA] = ea; <32--> cpu.gpr[RT] = read_long(reg0(RA) + ext16(D)); <31--><23------>. cpu.gpr[RT] = read_long(reg0(RA) + reg(RB)); <33--> uint32_t ea = reg(RA) + ext16(D); cpu.gpr[RT] = read_long(ea); cpu.gpr[RA] = ea; <31--><55------>. uint32_t ea = reg(RA) + reg(RB); cpu.gpr[RT] = read_long(ea); cpu.gpr[RA] = ea; <58-->10 cpu.gpr[RT] = read_long(reg0(RA) + ext16(DS<<2)); <31--><341----->. cpu.gpr[RT] = read_long(reg0(RA) + reg(RB)); <31--><373----->. uint32_t ea = reg(RA) + reg(RB); cpu.gpr[RT] = read_long(ea); cpu.gpr[RA] = ea; # Fixed point stores <38--> write_byte(reg0(RA) + ext16(D), reg(RS)); <31--><215----->. write_byte(reg0(RA) + reg(RB), reg(RS)); <39--> uint32_t ea = reg(RA) + ext16(D); write_byte(ea, reg(RS)); cpu.gpr[RA] = ea; <31--><247----->. uint32_t ea = reg(RA) + reg(RB); write_byte(ea, reg(RS)); cpu.gpr[RA] = ea; <44--> write_word(reg0(RA) + ext16(D), reg(RS)); <31--><407----->. write_word(reg0(RA) + reg(RB), reg(RS)); <45--> uint32_t ea = reg(RA) + ext16(D); write_word(ea, reg(RS)); cpu.gpr[RA] = ea; <31--><439----->. uint32_t ea = reg(RA) + reg(RB); write_word(ea, reg(RS)); cpu.gpr[RA] = ea; <36--> write_long(reg0(RA) + ext16(D), reg(RS)); <31--><151----->. write_long(reg0(RA) + reg(RB), reg(RS)); <37--> uint32_t ea = reg(RA) + ext16(D); write_long(ea, reg(RS)); cpu.gpr[RA] = ea; <31--><183----->. uint32_t ea = reg(RA) + reg(RB); write_long(ea, reg(RS)); cpu.gpr[RA] = ea; # Fixed point load/stores with byte reversal <31--><790----->. cpu.gpr[RT] = swb16(read_word(reg0(RA) + reg(RB))); <31--><534----->. cpu.gpr[RT] = swb32(read_long(reg0(RA) + reg(RB))); <31--><918----->. write_word(reg0(RA) + reg(RB), swb16(reg(RS))); <31--><662----->. write_long(reg0(RA) + reg(RB), swb32(reg(RS))); # Load/store multiple <46--> read_multiple(reg0(RA) + ext16(D), RT); <47--> write_multiple(reg0(RA) + ext16(D), RS); <31--><597----->. read_string(reg0(RA), RT, NB ? NB : 32); <31--><533----->. read_string(reg0(RA) + reg(RB), RT, cpu.xer & 0x1f); <31--><725----->. write_string(reg0(RA), RS, NB ? NB : 32); <31--><661----->. write_string(reg0(RA) + reg(RB), RS, cpu.xer & 0x1f); # ALU instructions <14--> cpu.gpr[RT] = reg0(RA) + ext16(SI); <15--> cpu.gpr[RT] = reg0(RA) + (SI<<16); <31-->O<266---->R setcr0(R, cpu.gpr[RT] = addo(reg(RA), reg(RB), 0, O, 0)); <31-->O<40----->R setcr0(R, cpu.gpr[RT] = addo(~reg(RA), reg(RB), 1, O, 0)); <6-->R cpu.gpr[RT] = addo(reg(RA), ext16(SI), 0, 0, 1); <8---> cpu.gpr[RT] = addo(~reg(RA), ext16(SI), 1, 0, 1); <31-->O<10----->R setcr0(R, cpu.gpr[RT] = addo(reg(RA), reg(RB), 0, O, 1)); <31-->O<8------>R setcr0(R, cpu.gpr[RT] = addo(~reg(RA), reg(RB), 1, O, 1)); <31-->O<138---->R setcr0(R, cpu.gpr[RT] = addo(reg(RA), reg(RB), carry(), O, 1)); <31-->O<136---->R setcr0(R, cpu.gpr[RT] = addo(~reg(RA), reg(RB), carry(), O, 1)); <31-->.....O<234---->R setcr0(R, cpu.gpr[RT] = addo(reg(RA), -1, carry(), O, 1)); <31-->.....O<232---->R setcr0(R, cpu.gpr[RT] = addo(~reg(RA), -1, carry(), O, 1)); <31-->.....O<202---->R setcr0(R, cpu.gpr[RT] = addo(reg(RA), 0, carry(), O, 1)); <31-->.....O<200---->R setcr0(R, cpu.gpr[RT] = addo(~reg(RA), 0, carry(), O, 1)); <31-->.....O<104---->R setcr0(R, cpu.gpr[RT] = addo(~reg(RA), 0, 1, O, 0)); <7---> cpu.gpr[RT] = reg(RA) * ext16(SI); <31-->O<235---->R setcr0(R, cpu.gpr[RT] = mulo(reg(RA), reg(RB), O)); <31-->O<491---->R setcr0(R, cpu.gpr[RT] = divo(reg(RA), reg(RB), O)); <31-->O<459---->R setcr0(R, cpu.gpr[RT] = divuo(reg(RA), reg(RB), O)); # Comparison instructions <11-->.0 compares(reg(RA), ext16(SI), F); <31-->.0<0------->. compares(reg(RA), reg(RB), F); <10-->.0 compareu(reg(RA), UI, F); <31-->.0<32------>. compareu(reg(RA), reg(RB), F); # Logical instructions <28--> cpu.gpr[RA] = reg(RS) & UI; <29--> cpu.gpr[RA] = reg(RS) & (UI<<16); <24--> cpu.gpr[RA] = reg(RS) | UI; <25--> cpu.gpr[RA] = reg(RS) | (UI<<16); <26--> cpu.gpr[RA] = reg(RS) ^ UI; <27--> cpu.gpr[RA] = reg(RS) ^ (UI<<16); <31--><28------>R setcr0(R, cpu.gpr[RA] = reg(RS) & reg(RB)); <31--><444----->R setcr0(R, cpu.gpr[RA] = reg(RS) | reg(RB)); <31--><316----->R setcr0(R, cpu.gpr[RA] = reg(RS) ^ reg(RB)); <31--><476----->R setcr0(R, cpu.gpr[RA] = ~(reg(RS) & reg(RB))); <31--><124----->R setcr0(R, cpu.gpr[RA] = ~(reg(RS) | reg(RB))); <31--><284----->R setcr0(R, cpu.gpr[RA] = ~(reg(RS) ^ reg(RB))); <31--><60------>R setcr0(R, cpu.gpr[RA] = reg(RS) & ~reg(RB)); <31--><412----->R setcr0(R, cpu.gpr[RA] = reg(RS) | ~reg(RB)); <31-->.....<954----->R setcr0(R, cpu.gpr[RA] = ext8(reg(RS))); <31-->.....<922----->R setcr0(R, cpu.gpr[RA] = ext16(reg(RS))); <31-->.....<26------>R setcr0(R, cpu.gpr[RA] = cntlzw(reg(RS))); <31-->.....<122----->R setcr0(R, cpu.gpr[RA] = popcntb(reg(RS))); # Rotation/shift instructions <21-->R setcr0(R, cpu.gpr[RA] = rlwnm(reg(RS), SH, MB, ME)); <23-->R setcr0(R, cpu.gpr[RA] = rlwnm(reg(RS), reg(RB), MB, ME)); <20-->R setcr0(R, cpu.gpr[RA] = rlwmi(reg(RS), SH, MB, ME)); <31--><24------>R setcr0(R, cpu.gpr[RA] = reg(RS) << (reg(RB) & 0x1f)); <31--><536----->R setcr0(R, cpu.gpr[RA] = reg(RS) >> (reg(RB) & 0x1f)); <31--><824----->R setcr0(R, cpu.gpr[RA] = ((int32_t)reg(RS)) >> SH); <31--><792----->R setcr0(R, cpu.gpr[RA] = ((int32_t)reg(RS)) >> (reg(RB) & 0x1f)); # Move to/from special registers <31--><1-->00000<467----->. cpu.xer = reg(RS); <31--><8-->00000<467----->. cpu.lr = reg(RS); <31--><9-->00000<467----->. cpu.ctr = reg(RS); <31--><1-->00000<339----->. cpu.gpr[RT] = cpu.xer; <31--><8-->00000<339----->. cpu.gpr[RT] = cpu.lr; <31--><9-->00000<339----->. cpu.gpr[RT] = cpu.ctr; <31-->0.<144----->. mtcrf(FXM, reg(RS)); <31-->0.........<19------>. cpu.gpr[RT] = cpu.cr; # Floating pointer operations follow. # # These are extremely crude, and just enough has been implemented to make the # tests pass. The FPSCR bits are all ignored completely. # FPSCR manipulation <63-->..........<583----->R fatal("mffs not supported"); <63-->.........<64------>. fatal("mcrfs not supported"); <63-->........<134----->R fatal("mtsfsfi not supported"); <63-->..<711----->R fatal("mtfsf not supported"); <63-->..........<70------>R fatal("mtfsb0 not supported"); <63-->..........<38------>R fatal("mtfsb1 not supported"); # Floating point double loads (raw bits) <50--> cpu.fpr[FRT] = read_double(reg0(RA) + ext16(D)); <31--><599----->. cpu.fpr[FRT] = read_double(reg0(RA) + reg(RB)); <51--> uint32_t ea = reg(RA) + ext16(D); cpu.fpr[FRT] = read_double(ea); cpu.gpr[RA] = ea; <31--><631----->. uint32_t ea = reg(RA) + reg(RB); cpu.fpr[FRT] = read_double(ea); cpu.gpr[RA] = ea; # Floating point double stores (raw bits) <54--> write_double(reg0(RA) + ext16(D), cpu.fpr[FRS]); <31--><727----->. write_double(reg0(RA) + reg(RB), cpu.fpr[FRS]); <55--> uint32_t ea = reg(RA) + ext16(D); write_double(ea, cpu.fpr[FRS]); cpu.gpr[RA] = ea; <31--><759----->. uint32_t ea = reg(RA) + reg(RB); write_double(ea, cpu.fpr[FRS]); cpu.gpr[RA] = ea; # Floating point single loads (convert from single to double) <48--> cpu.fpr[FRT] = d2b(b2f(read_long(reg0(RA) + ext16(D)))); <31--><535----->. cpu.fpr[FRT] = d2b(b2f(read_long(reg0(RA) + reg(RB)))); <49--> uint32_t ea = reg(RA) + ext16(D); cpu.fpr[FRT] = d2b(b2f(read_long(ea))); cpu.gpr[RA] = ea; <31--><567----->. uint32_t ea = reg(RA) + reg(RB); cpu.fpr[FRT] = d2b(b2f(read_long(ea))); cpu.gpr[RA] = ea; # Floating point single stores (convert from double to single) <52--> write_long(reg0(RA) + ext16(D), f2b(fpr(FRS))); <31--><663----->. write_long(reg0(RA) + reg(RB), f2b(fpr(FRS))); <53--> uint32_t ea = reg(RA) + ext16(D); write_long(ea, f2b(fpr(FRS))); cpu.gpr[RA] = ea; <31--><695----->. uint32_t ea = reg(RA) + reg(RB); write_long(ea, f2b(fpr(FRS))); cpu.gpr[RA] = ea; # Floating point arithmetic <63-->.....<72------>R setcr1(R, cpu.fpr[FRT] = cpu.fpr[FRB]); <63-->.....<40------>R setcr1(R, cpu.fpr[FRT] = d2b(-fpr(FRB))); <63-->.....<264----->R setcr1(R, cpu.fpr[FRT] = d2b(fabs(fpr(FRB)))); <63-->.....<136----->R setcr1(R, cpu.fpr[FRT] = d2b(-fabs(fpr(FRB)))); <63--><21------>R setcr1(R, cpu.fpr[FRT] = d2b(fpr(FRA) + fpr(FRB))); <63--><20------>R setcr1(R, cpu.fpr[FRT] = d2b(fpr(FRA) - fpr(FRB))); <63--><25------>R setcr1(R, cpu.fpr[FRT] = d2b(fpr(FRA) * fpr(FRB))); <63--><18------>R setcr1(R, cpu.fpr[FRT] = d2b(fpr(FRA) / fpr(FRB))); # Floating point comparisons <63-->..<0------->. comparef(fpr(FRA), fpr(FRB), F); <63-->..<32------>. comparef(fpr(FRA), fpr(FRB), F); # Floating point conversions <63-->.....<14------>R setcr1(R, fpr(FRB)); cpu.fpr[FRT] = (uint32_t)fpr(FRB); <63-->.....<15------>R setcr1(R, fpr(FRB)); cpu.fpr[FRT] = (uint32_t)fpr(FRB);