594 lines
20 KiB
Text
594 lines
20 KiB
Text
|
// -*- mode:c++ -*-
|
||
|
|
||
|
// Copyright (c) 2009 The University of Edinburgh
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// Redistribution and use in source and binary forms, with or without
|
||
|
// modification, are permitted provided that the following conditions are
|
||
|
// met: redistributions of source code must retain the above copyright
|
||
|
// notice, this list of conditions and the following disclaimer;
|
||
|
// redistributions in binary form must reproduce the above copyright
|
||
|
// notice, this list of conditions and the following disclaimer in the
|
||
|
// documentation and/or other materials provided with the distribution;
|
||
|
// neither the name of the copyright holders nor the names of its
|
||
|
// contributors may be used to endorse or promote products derived from
|
||
|
// this software without specific prior written permission.
|
||
|
//
|
||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
//
|
||
|
// Authors: Timothy M. Jones
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// The actual Power ISA decoder
|
||
|
// ------------------------------
|
||
|
//
|
||
|
// I've used the Power ISA Book I v2.06 for instruction formats,
|
||
|
// opcode numbers, register names, etc.
|
||
|
//
|
||
|
decode OPCODE default Unknown::unknown() {
|
||
|
|
||
|
format IntImmOp {
|
||
|
10: cmpli({{
|
||
|
Xer xer = XER;
|
||
|
uint32_t cr = makeCRField(Ra, (uint32_t)uimm, xer.so);
|
||
|
CR = insertCRField(CR, BF, cr);
|
||
|
}});
|
||
|
11: cmpi({{
|
||
|
Xer xer = XER;
|
||
|
uint32_t cr = makeCRField(Ra.sw, (int32_t)imm, xer.so);
|
||
|
CR = insertCRField(CR, BF, cr);
|
||
|
}});
|
||
|
}
|
||
|
|
||
|
// Some instructions use bits 21 - 30, others 22 - 30. We have to use
|
||
|
// the larger size to account for all opcodes. For those that use the
|
||
|
// smaller value, the OE bit is bit 21. Therefore, we have two versions
|
||
|
// of each instruction: 1 with OE set, the other without. For an
|
||
|
// example see 'add' and 'addo'.
|
||
|
31: decode XO_XO {
|
||
|
|
||
|
// These instructions can all be reduced to the form
|
||
|
// Rt = src1 + src2 [+ CA], therefore we just give src1 and src2
|
||
|
// (and, if necessary, CA) definitions and let the python script
|
||
|
// deal with setting things up correctly. We also give flags to
|
||
|
// say which control registers to set.
|
||
|
format IntSumOp {
|
||
|
266: add({{ Ra }}, {{ Rb }});
|
||
|
40: subf({{ ~Ra }}, {{ Rb }}, {{ 1 }});
|
||
|
10: addc({{ Ra }}, {{ Rb }},
|
||
|
computeCA = true);
|
||
|
8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }},
|
||
|
true);
|
||
|
104: neg({{ ~Ra }}, {{ 1 }});
|
||
|
138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }},
|
||
|
true);
|
||
|
234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }},
|
||
|
true);
|
||
|
136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }},
|
||
|
true);
|
||
|
232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }},
|
||
|
true);
|
||
|
202: addze({{ Ra }}, {{ xer.ca }},
|
||
|
computeCA = true);
|
||
|
200: subfze({{ ~Ra }}, {{ xer.ca }},
|
||
|
computeCA = true);
|
||
|
}
|
||
|
|
||
|
// Arithmetic instructions all use source registers Ra and Rb,
|
||
|
// with destination register Rt.
|
||
|
format IntArithOp {
|
||
|
75: mulhw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod >> 32; }});
|
||
|
11: mulhwu({{ uint64_t prod = Ra.uq * Rb.uq; Rt = prod >> 32; }});
|
||
|
235: mullw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod; }});
|
||
|
747: mullwo({{ int64_t src1 = Ra.sq; int64_t src2 = Rb; int64_t prod = src1 * src2; Rt = prod; }},
|
||
|
true);
|
||
|
|
||
|
491: divw({{
|
||
|
int32_t src1 = Ra.sw;
|
||
|
int32_t src2 = Rb.sw;
|
||
|
if ((src1 != 0x80000000 || src2 != 0xffffffff)
|
||
|
&& src2 != 0) {
|
||
|
Rt = src1 / src2;
|
||
|
} else {
|
||
|
Rt = 0;
|
||
|
}
|
||
|
}});
|
||
|
|
||
|
1003: divwo({{
|
||
|
int32_t src1 = Ra.sw;
|
||
|
int32_t src2 = Rb.sw;
|
||
|
if ((src1 != 0x80000000 || src2 != 0xffffffff)
|
||
|
&& src2 != 0) {
|
||
|
Rt = src1 / src2;
|
||
|
} else {
|
||
|
Rt = 0;
|
||
|
divSetOV = true;
|
||
|
}
|
||
|
}},
|
||
|
true);
|
||
|
|
||
|
459: divwu({{
|
||
|
uint32_t src1 = Ra.sw;
|
||
|
uint32_t src2 = Rb.sw;
|
||
|
if (src2 != 0) {
|
||
|
Rt = src1 / src2;
|
||
|
} else {
|
||
|
Rt = 0;
|
||
|
}
|
||
|
}});
|
||
|
|
||
|
971: divwuo({{
|
||
|
uint32_t src1 = Ra.sw;
|
||
|
uint32_t src2 = Rb.sw;
|
||
|
if (src2 != 0) {
|
||
|
Rt = src1 / src2;
|
||
|
} else {
|
||
|
Rt = 0;
|
||
|
divSetOV = true;
|
||
|
}
|
||
|
}},
|
||
|
true);
|
||
|
}
|
||
|
|
||
|
// Integer logic instructions use source registers Rs and Rb,
|
||
|
// with destination register Ra.
|
||
|
format IntLogicOp {
|
||
|
28: and({{ Ra = Rs & Rb; }});
|
||
|
316: xor({{ Ra = Rs ^ Rb; }});
|
||
|
476: nand({{ Ra = ~(Rs & Rb); }});
|
||
|
444: or({{ Ra = Rs | Rb; }});
|
||
|
124: nor({{ Ra = ~(Rs | Rb); }});
|
||
|
60: andc({{ Ra = Rs & ~Rb; }});
|
||
|
954: extsb({{ Ra = sext<8>(Rs); }});
|
||
|
284: eqv({{ Ra = ~(Rs ^ Rb); }});
|
||
|
412: orc({{ Ra = Rs | ~Rb; }});
|
||
|
922: extsh({{ Ra = sext<16>(Rs); }});
|
||
|
26: cntlzw({{ Ra = Rs == 0 ? 32 : 31 - findMsbSet(Rs); }});
|
||
|
508: cmpb({{
|
||
|
uint32_t val = 0;
|
||
|
for (int n = 0; n < 32; n += 8) {
|
||
|
if(bits(Rs, n, n+7) == bits(Rb, n, n+7)) {
|
||
|
val = insertBits(val, n, n+7, 0xff);
|
||
|
}
|
||
|
}
|
||
|
Ra = val;
|
||
|
}});
|
||
|
|
||
|
24: slw({{
|
||
|
if (Rb & 0x20) {
|
||
|
Ra = 0;
|
||
|
} else {
|
||
|
Ra = Rs << (Rb & 0x1f);
|
||
|
}
|
||
|
}});
|
||
|
|
||
|
536: srw({{
|
||
|
if (Rb & 0x20) {
|
||
|
Ra = 0;
|
||
|
} else {
|
||
|
Ra = Rs >> (Rb & 0x1f);
|
||
|
}
|
||
|
}});
|
||
|
|
||
|
792: sraw({{
|
||
|
bool shiftSetCA = false;
|
||
|
int32_t s = Rs;
|
||
|
if (Rb == 0) {
|
||
|
Ra = Rs;
|
||
|
shiftSetCA = true;
|
||
|
} else if (Rb & 0x20) {
|
||
|
if (s < 0) {
|
||
|
Ra = (uint32_t)-1;
|
||
|
if (s & 0x7fffffff) {
|
||
|
shiftSetCA = true;
|
||
|
} else {
|
||
|
shiftSetCA = false;
|
||
|
}
|
||
|
} else {
|
||
|
Ra = 0;
|
||
|
shiftSetCA = false;
|
||
|
}
|
||
|
} else {
|
||
|
Ra = s >> (Rb & 0x1f);
|
||
|
if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) {
|
||
|
shiftSetCA = true;
|
||
|
} else {
|
||
|
shiftSetCA = false;
|
||
|
}
|
||
|
}
|
||
|
Xer xer1 = XER;
|
||
|
if (shiftSetCA) {
|
||
|
xer1.ca = 1;
|
||
|
} else {
|
||
|
xer1.ca = 0;
|
||
|
}
|
||
|
XER = xer1;
|
||
|
}});
|
||
|
}
|
||
|
|
||
|
// Integer logic instructions with a shift value.
|
||
|
format IntShiftOp {
|
||
|
824: srawi({{
|
||
|
bool shiftSetCA = false;
|
||
|
if (sh == 0) {
|
||
|
Ra = Rs;
|
||
|
shiftSetCA = false;
|
||
|
} else {
|
||
|
int32_t s = Rs;
|
||
|
Ra = s >> sh;
|
||
|
if (s < 0 && (s << (32 - sh)) != 0) {
|
||
|
shiftSetCA = true;
|
||
|
} else {
|
||
|
shiftSetCA = false;
|
||
|
}
|
||
|
}
|
||
|
Xer xer1 = XER;
|
||
|
if (shiftSetCA) {
|
||
|
xer1.ca = 1;
|
||
|
} else {
|
||
|
xer1.ca = 0;
|
||
|
}
|
||
|
XER = xer1;
|
||
|
}});
|
||
|
}
|
||
|
|
||
|
// Generic integer format instructions.
|
||
|
format IntOp {
|
||
|
0: cmp({{
|
||
|
Xer xer = XER;
|
||
|
uint32_t cr = makeCRField(Ra.sw, Rb.sw, xer.so);
|
||
|
CR = insertCRField(CR, BF, cr);
|
||
|
}});
|
||
|
32: cmpl({{
|
||
|
Xer xer = XER;
|
||
|
uint32_t cr = makeCRField(Ra, Rb, xer.so);
|
||
|
CR = insertCRField(CR, BF, cr);
|
||
|
}});
|
||
|
144: mtcrf({{
|
||
|
uint32_t mask = 0;
|
||
|
for (int i = 0; i < 8; ++i) {
|
||
|
if (((FXM >> i) & 0x1) == 0x1) {
|
||
|
mask |= 0xf << (4 * i);
|
||
|
}
|
||
|
}
|
||
|
CR = (Rs & mask) | (CR & ~mask);
|
||
|
}});
|
||
|
19: mfcr({{ Rt = CR; }});
|
||
|
339: decode SPR {
|
||
|
0x20: mfxer({{ Rt = XER; }});
|
||
|
0x100: mflr({{ Rt = LR; }});
|
||
|
0x120: mfctr({{ Rt = CTR; }});
|
||
|
}
|
||
|
467: decode SPR {
|
||
|
0x20: mtxer({{ XER = Rs; }});
|
||
|
0x100: mtlr({{ LR = Rs; }});
|
||
|
0x120: mtctr({{ CTR = Rs; }});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// All loads with an index register. The non-update versions
|
||
|
// all use the value 0 if Ra == R0, not the value contained in
|
||
|
// R0. Others update Ra with the effective address. In all cases,
|
||
|
// Ra and Rb are source registers, Rt is the destintation.
|
||
|
format LoadIndexOp {
|
||
|
87: lbzx({{ Rt = Mem.ub; }});
|
||
|
279: lhzx({{ Rt = Mem.uh; }});
|
||
|
343: lhax({{ Rt = Mem.sh; }});
|
||
|
23: lwzx({{ Rt = Mem; }});
|
||
|
341: lwax({{ Rt = Mem.sw; }});
|
||
|
20: lwarx({{ Rt = Mem.sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }});
|
||
|
535: lfsx({{ Ft.sf = Mem.sf; }});
|
||
|
599: lfdx({{ Ft = Mem.df; }});
|
||
|
855: lfiwax({{ Ft.uw = Mem; }});
|
||
|
}
|
||
|
|
||
|
format LoadIndexUpdateOp {
|
||
|
119: lbzux({{ Rt = Mem.ub; }});
|
||
|
311: lhzux({{ Rt = Mem.uh; }});
|
||
|
375: lhaux({{ Rt = Mem.sh; }});
|
||
|
55: lwzux({{ Rt = Mem; }});
|
||
|
373: lwaux({{ Rt = Mem.sw; }});
|
||
|
567: lfsux({{ Ft.sf = Mem.sf; }});
|
||
|
631: lfdux({{ Ft = Mem.df; }});
|
||
|
}
|
||
|
|
||
|
format StoreIndexOp {
|
||
|
215: stbx({{ Mem.ub = Rs.ub; }});
|
||
|
407: sthx({{ Mem.uh = Rs.uh; }});
|
||
|
151: stwx({{ Mem = Rs; }});
|
||
|
150: stwcx({{
|
||
|
bool store_performed = false;
|
||
|
if (Rsv) {
|
||
|
if (RsvLen == 4) {
|
||
|
if (RsvAddr == EA) {
|
||
|
Mem = Rs;
|
||
|
store_performed = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Xer xer = XER;
|
||
|
Cr cr = CR;
|
||
|
cr.cr0 = ((store_performed ? 0x2 : 0x0) | xer.so);
|
||
|
CR = cr;
|
||
|
Rsv = 0;
|
||
|
}});
|
||
|
663: stfsx({{ Mem.sf = Fs.sf; }});
|
||
|
727: stfdx({{ Mem.df = Fs; }});
|
||
|
983: stfiwx({{ Mem = Fs.uw; }});
|
||
|
}
|
||
|
|
||
|
format StoreIndexUpdateOp {
|
||
|
247: stbux({{ Mem.ub = Rs.ub; }});
|
||
|
439: sthux({{ Mem.uh = Rs.uh; }});
|
||
|
183: stwux({{ Mem = Rs; }});
|
||
|
695: stfsux({{ Mem.sf = Fs.sf; }});
|
||
|
759: stfdux({{ Mem.df = Fs; }});
|
||
|
}
|
||
|
|
||
|
// These instructions all provide data cache hints
|
||
|
format MiscOp {
|
||
|
278: dcbt({{ }});
|
||
|
246: dcbtst({{ }});
|
||
|
598: sync({{ }}, [ IsMemBarrier ]);
|
||
|
854: eieio({{ }}, [ IsMemBarrier ]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
format IntImmArithCheckRaOp {
|
||
|
14: addi({{ Rt = Ra + imm; }},
|
||
|
{{ Rt = imm }});
|
||
|
15: addis({{ Rt = Ra + (imm << 16); }},
|
||
|
{{ Rt = imm << 16; }});
|
||
|
}
|
||
|
|
||
|
format IntImmArithOp {
|
||
|
12: addic({{ uint32_t src = Ra; Rt = src + imm; }},
|
||
|
[computeCA]);
|
||
|
13: addic_({{ uint32_t src = Ra; Rt = src + imm; }},
|
||
|
[computeCA, computeCR0]);
|
||
|
8: subfic({{ int32_t src = ~Ra; Rt = src + imm + 1; }},
|
||
|
[computeCA]);
|
||
|
7: mulli({{
|
||
|
int32_t src = Ra.sw;
|
||
|
int64_t prod = src * imm;
|
||
|
Rt = (uint32_t)prod;
|
||
|
}});
|
||
|
}
|
||
|
|
||
|
format IntImmLogicOp {
|
||
|
24: ori({{ Ra = Rs | uimm; }});
|
||
|
25: oris({{ Ra = Rs | (uimm << 16); }});
|
||
|
26: xori({{ Ra = Rs ^ uimm; }});
|
||
|
27: xoris({{ Ra = Rs ^ (uimm << 16); }});
|
||
|
28: andi_({{ Ra = Rs & uimm; }},
|
||
|
true);
|
||
|
29: andis_({{ Ra = Rs & (uimm << 16); }},
|
||
|
true);
|
||
|
}
|
||
|
|
||
|
16: decode AA {
|
||
|
|
||
|
// Conditionally branch relative to PC based on CR and CTR.
|
||
|
format BranchPCRelCondCtr {
|
||
|
0: bc({{ NPC = PC + disp; }});
|
||
|
}
|
||
|
|
||
|
// Conditionally branch to fixed address based on CR and CTR.
|
||
|
format BranchNonPCRelCondCtr {
|
||
|
1: bca({{ NPC = targetAddr; }});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
18: decode AA {
|
||
|
|
||
|
// Unconditionally branch relative to PC.
|
||
|
format BranchPCRel {
|
||
|
0: b({{ NPC = PC + disp; }});
|
||
|
}
|
||
|
|
||
|
// Unconditionally branch to fixed address.
|
||
|
format BranchNonPCRel {
|
||
|
1: ba({{ NPC = targetAddr; }});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
19: decode XO_XO {
|
||
|
|
||
|
// Conditionally branch to address in LR based on CR and CTR.
|
||
|
format BranchLrCondCtr {
|
||
|
16: bclr({{ NPC = LR & 0xfffffffc; }});
|
||
|
}
|
||
|
|
||
|
// Conditionally branch to address in CTR based on CR.
|
||
|
format BranchCtrCond {
|
||
|
528: bcctr({{ NPC = CTR & 0xfffffffc; }});
|
||
|
}
|
||
|
|
||
|
// Condition register manipulation instructions.
|
||
|
format CondLogicOp {
|
||
|
257: crand({{
|
||
|
uint32_t crBa = bits(CR, 31 - ba);
|
||
|
uint32_t crBb = bits(CR, 31 - bb);
|
||
|
CR = insertBits(CR, 31 - bt, crBa & crBb);
|
||
|
}});
|
||
|
449: cror({{
|
||
|
uint32_t crBa = bits(CR, 31 - ba);
|
||
|
uint32_t crBb = bits(CR, 31 - bb);
|
||
|
CR = insertBits(CR, 31 - bt, crBa | crBb);
|
||
|
}});
|
||
|
255: crnand({{
|
||
|
uint32_t crBa = bits(CR, 31 - ba);
|
||
|
uint32_t crBb = bits(CR, 31 - bb);
|
||
|
CR = insertBits(CR, 31 - bt, !(crBa & crBb));
|
||
|
}});
|
||
|
193: crxor({{
|
||
|
uint32_t crBa = bits(CR, 31 - ba);
|
||
|
uint32_t crBb = bits(CR, 31 - bb);
|
||
|
CR = insertBits(CR, 31 - bt, crBa ^ crBb);
|
||
|
}});
|
||
|
33: crnor({{
|
||
|
uint32_t crBa = bits(CR, 31 - ba);
|
||
|
uint32_t crBb = bits(CR, 31 - bb);
|
||
|
CR = insertBits(CR, 31 - bt, !(crBa | crBb));
|
||
|
}});
|
||
|
289: creqv({{
|
||
|
uint32_t crBa = bits(CR, 31 - ba);
|
||
|
uint32_t crBb = bits(CR, 31 - bb);
|
||
|
CR = insertBits(CR, 31 - bt, crBa == crBb);
|
||
|
}});
|
||
|
129: crandc({{
|
||
|
uint32_t crBa = bits(CR, 31 - ba);
|
||
|
uint32_t crBb = bits(CR, 31 - bb);
|
||
|
CR = insertBits(CR, 31 - bt, crBa & !crBb);
|
||
|
}});
|
||
|
417: crorc({{
|
||
|
uint32_t crBa = bits(CR, 31 - ba);
|
||
|
uint32_t crBb = bits(CR, 31 - bb);
|
||
|
CR = insertBits(CR, 31 - bt, crBa | !crBb);
|
||
|
}});
|
||
|
}
|
||
|
format CondMoveOp {
|
||
|
0: mcrf({{
|
||
|
uint32_t crBfa = bits(CR, 31 - bfa*4, 28 - bfa*4);
|
||
|
CR = insertBits(CR, 31 - bf*4, 28 - bf*4, crBfa);
|
||
|
}});
|
||
|
}
|
||
|
format MiscOp {
|
||
|
150: isync({{ }}, [ IsSerializeAfter ]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
format IntRotateOp {
|
||
|
21: rlwinm({{ Ra = rotateValue(Rs, sh) & fullMask; }});
|
||
|
23: rlwnm({{ Ra = rotateValue(Rs, Rb) & fullMask; }});
|
||
|
20: rlwimi({{ Ra = (rotateValue(Rs, sh) & fullMask) | (Ra & ~fullMask); }});
|
||
|
}
|
||
|
|
||
|
format LoadDispOp {
|
||
|
34: lbz({{ Rt = Mem.ub; }});
|
||
|
40: lhz({{ Rt = Mem.uh; }});
|
||
|
42: lha({{ Rt = Mem.sh; }});
|
||
|
32: lwz({{ Rt = Mem; }});
|
||
|
58: lwa({{ Rt = Mem.sw; }},
|
||
|
{{ EA = Ra + (disp & 0xfffffffc); }},
|
||
|
{{ EA = disp & 0xfffffffc; }});
|
||
|
48: lfs({{ Ft.sf = Mem.sf; }});
|
||
|
50: lfd({{ Ft = Mem.df; }});
|
||
|
}
|
||
|
|
||
|
format LoadDispUpdateOp {
|
||
|
35: lbzu({{ Rt = Mem.ub; }});
|
||
|
41: lhzu({{ Rt = Mem.uh; }});
|
||
|
43: lhau({{ Rt = Mem.sh; }});
|
||
|
33: lwzu({{ Rt = Mem; }});
|
||
|
49: lfsu({{ Ft.sf = Mem.sf; }});
|
||
|
51: lfdu({{ Ft = Mem.df; }});
|
||
|
}
|
||
|
|
||
|
format StoreDispOp {
|
||
|
38: stb({{ Mem.ub = Rs.ub; }});
|
||
|
44: sth({{ Mem.uh = Rs.uh; }});
|
||
|
36: stw({{ Mem = Rs; }});
|
||
|
52: stfs({{ Mem.sf = Fs.sf; }});
|
||
|
54: stfd({{ Mem.df = Fs; }});
|
||
|
}
|
||
|
|
||
|
format StoreDispUpdateOp {
|
||
|
39: stbu({{ Mem.ub = Rs.ub; }});
|
||
|
45: sthu({{ Mem.uh = Rs.uh; }});
|
||
|
37: stwu({{ Mem = Rs; }});
|
||
|
53: stfsu({{ Mem.sf = Fs.sf; }});
|
||
|
55: stfdu({{ Mem.df = Fs; }});
|
||
|
}
|
||
|
|
||
|
17: IntOp::sc({{ xc->syscall(R0); }},
|
||
|
[ IsSyscall, IsNonSpeculative, IsSerializeAfter ]);
|
||
|
|
||
|
format FloatArithOp {
|
||
|
59: decode A_XO {
|
||
|
21: fadds({{ Ft = Fa + Fb; }});
|
||
|
20: fsubs({{ Ft = Fa - Fb; }});
|
||
|
25: fmuls({{ Ft = Fa * Fc; }});
|
||
|
18: fdivs({{ Ft = Fa / Fb; }});
|
||
|
29: fmadds({{ Ft = (Fa * Fc) + Fb; }});
|
||
|
28: fmsubs({{ Ft = (Fa * Fc) - Fb; }});
|
||
|
31: fnmadds({{ Ft = -((Fa * Fc) + Fb); }});
|
||
|
30: fnmsubs({{ Ft = -((Fa * Fc) - Fb); }});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
63: decode A_XO {
|
||
|
format FloatArithOp {
|
||
|
21: fadd({{ Ft = Fa + Fb; }});
|
||
|
20: fsub({{ Ft = Fa - Fb; }});
|
||
|
25: fmul({{ Ft = Fa * Fc; }});
|
||
|
18: fdiv({{ Ft = Fa / Fb; }});
|
||
|
29: fmadd({{ Ft = (Fa * Fc) + Fb; }});
|
||
|
28: fmsub({{ Ft = (Fa * Fc) - Fb; }});
|
||
|
31: fnmadd({{ Ft = -((Fa * Fc) + Fb); }});
|
||
|
30: fnmsub({{ Ft = -((Fa * Fc) - Fb); }});
|
||
|
}
|
||
|
|
||
|
default: decode XO_XO {
|
||
|
format FloatConvertOp {
|
||
|
12: frsp({{ Ft.sf = Fb; }});
|
||
|
15: fctiwz({{ Ft.sw = (int32_t)trunc(Fb); }});
|
||
|
}
|
||
|
|
||
|
format FloatOp {
|
||
|
0: fcmpu({{
|
||
|
uint32_t c = makeCRField(Fa, Fb);
|
||
|
Fpscr fpscr = FPSCR;
|
||
|
fpscr.fprf.fpcc = c;
|
||
|
FPSCR = fpscr;
|
||
|
CR = insertCRField(CR, BF, c);
|
||
|
}});
|
||
|
}
|
||
|
|
||
|
format FloatRCCheckOp {
|
||
|
72: fmr({{ Ft = Fb; }});
|
||
|
264: fabs({{
|
||
|
Ft.uq = Fb.uq;
|
||
|
Ft.uq = insertBits(Ft.uq, 63, 0); }});
|
||
|
136: fnabs({{
|
||
|
Ft.uq = Fb.uq;
|
||
|
Ft.uq = insertBits(Ft.uq, 63, 1); }});
|
||
|
40: fneg({{ Ft = -Fb; }});
|
||
|
8: fcpsgn({{
|
||
|
Ft.uq = Fb.uq;
|
||
|
Ft.uq = insertBits(Ft.uq, 63, Fa.uq<63:63>);
|
||
|
}});
|
||
|
583: mffs({{ Ft.uq = FPSCR; }});
|
||
|
134: mtfsfi({{
|
||
|
FPSCR = insertCRField(FPSCR, BF + (8 * (1 - W)), U_FIELD);
|
||
|
}});
|
||
|
711: mtfsf({{
|
||
|
if (L == 1) { FPSCR = Fb.uq; }
|
||
|
else {
|
||
|
for (int i = 0; i < 8; ++i) {
|
||
|
if (bits(FLM, i) == 1) {
|
||
|
int k = 4 * (i + (8 * (1 - W)));
|
||
|
FPSCR = insertBits(FPSCR, k, k + 3,
|
||
|
bits(Fb.uq, k, k + 3));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}});
|
||
|
70: mtfsb0({{ FPSCR = insertBits(FPSCR, 31 - BT, 0); }});
|
||
|
38: mtfsb1({{ FPSCR = insertBits(FPSCR, 31 - BT, 1); }});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|