mirror of
https://github.com/elliotnunn/tbxi-patches.git
synced 2024-11-17 22:07:40 +00:00
200bc15b91
Makes command line use easier
555 lines
18 KiB
Python
Executable File
555 lines
18 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Copyright (c) 2019 Elliot Nunn
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
# copies or substantial portions of the Software.
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
|
|
# Dead-simple PowerPC assembler
|
|
# Usable as a library or an executable
|
|
|
|
|
|
import argparse
|
|
import sys
|
|
import re
|
|
import struct
|
|
import inspect
|
|
|
|
|
|
def assemble(asm, return_labels=False):
|
|
"""Assemble a string into a bytes object
|
|
"""
|
|
|
|
asm = asm.rstrip('\n').split('\n')
|
|
|
|
# First pass: discern labels from instructions
|
|
line_list = []
|
|
offset = 0
|
|
for lineno, orig_line in enumerate(asm, 1):
|
|
line = orig_line # mutate line a bit
|
|
line = line.lower() # normalize case
|
|
line = line.partition('#')[0] # strip comments
|
|
|
|
for line in line.split(';'):
|
|
line_labels, line = re.match(r'^((?:\s*\w+:)*)(.*)', line).groups()
|
|
|
|
line_labels = re.findall(r'\w+', line_labels)
|
|
line = line.strip()
|
|
|
|
line_list.append((lineno, offset, orig_line, line_labels, line))
|
|
|
|
if line: offset += 4
|
|
|
|
# Second pass: resolve labels (each instruction is 4 bytes, easy)
|
|
all_labels = {}
|
|
for lineno, offset, orig_line, line_labels, line in line_list:
|
|
for label in line_labels:
|
|
if label in all_labels:
|
|
raise SyntaxError('redefined label %s\n %d: %s' % (label, lineno, orig_line))
|
|
all_labels[label] = offset
|
|
|
|
# Third pass: assemble
|
|
binary = bytearray()
|
|
offset = 0
|
|
for lineno, offset, orig_line, line_labels, line in line_list:
|
|
if line:
|
|
cur_labels = {lab: lab_offset - offset for (lab, lab_offset) in all_labels.items()}
|
|
|
|
try:
|
|
binary.extend(struct.pack('>L', instruction(line, cur_labels)))
|
|
except SyntaxError as e:
|
|
e.msg += '\n %d: %s' % (lineno, orig_line.lstrip())
|
|
raise e
|
|
|
|
binary = bytes(binary)
|
|
|
|
if return_labels:
|
|
return binary, all_labels
|
|
else:
|
|
return binary
|
|
|
|
|
|
def instruction(line, variables):
|
|
# Enforce: inst[dot] args...
|
|
# with no whitespace anywhere
|
|
op = line.split()[0]
|
|
args = line[len(op):].split(',')
|
|
args = [a.strip() for a in args]
|
|
if args == ['']: args = []
|
|
dot = op.endswith('.')
|
|
if dot:
|
|
op = op[:-1]
|
|
|
|
# Get the function that will handle this instruction (special case for branches)
|
|
funcname = 'inst_' + (op.rstrip('l') if op.startswith('b') else op)
|
|
func = globals().get(funcname, None)
|
|
if not func: raise SyntaxError('unknown instruction')
|
|
|
|
# Special case: branch & link instructions take extra l as the first argument
|
|
if op.startswith('b'):
|
|
args.insert(0, str(int(op.endswith('l'))))
|
|
|
|
# Get the signature of the function, use that to parse the arguments
|
|
func_pattern = list(inspect.signature(func).parameters)
|
|
|
|
# Special case: instructions with extra '.'
|
|
if func_pattern[:1] == ['dot']:
|
|
args.insert(0, str(dot))
|
|
elif dot:
|
|
raise SyntaxError('dot not allowed')
|
|
|
|
# Expand bracketed arguments (load/store instructions) to two args
|
|
for i in range(len(func_pattern)):
|
|
if func_pattern[i].endswith('_bracket'):
|
|
func_pattern[i] = func_pattern[i][:-8]
|
|
m = re.match(r'^(.+?)\s*\(\s*(\w+)\s*\)$', args[i])
|
|
if m:
|
|
args[i:i+1] = m.groups() # expand to two arguments
|
|
else:
|
|
args[i:i+1] = ['', ''] # this will eventually fail...
|
|
|
|
# Insert optional arguments (as zeroes)
|
|
for i in range(len(func_pattern)):
|
|
if func_pattern[i].endswith('_optional'):
|
|
func_pattern[i] = func_pattern[i][:-9]
|
|
if len(args) < len(func_pattern):
|
|
args.insert(i, '0')
|
|
func_pattern[i] = 'anything' # do not attempt to validate
|
|
|
|
# Did the user give us the right number of commas?
|
|
if len(args) != len(func_pattern): raise SyntaxError('wrong number of args')
|
|
|
|
def eval_register_arg(x):
|
|
if x == 'sp': return 1
|
|
if x == 'rtoc': return 2
|
|
return int(x.lstrip('cr'))
|
|
|
|
def eval_expression(x):
|
|
def label_replacer(label):
|
|
label = label.group(0)
|
|
if label not in variables:
|
|
raise SyntaxError('undefined label: %s' % label)
|
|
return hex(variables[label])
|
|
|
|
replaced = re.sub(r'\b[^\W\d]\w*', label_replacer, x)
|
|
return eval(replaced, {"__builtins__": {}}, {})
|
|
|
|
# Create a validation regex and an evaluation function for each arg
|
|
validation_list = []
|
|
for pat in func_pattern:
|
|
if re.match(r'^r[A-Z]$', pat):
|
|
regex = r'^(sp|rtoc|r([0-9]|[12][0-9]|3[01]))$'
|
|
eval_func = eval_register_arg
|
|
elif re.match(r'^r[A-Z]0$', pat):
|
|
regex = r'^(0|sp|rtoc|r([1-9]|[12][0-9]|3[01]))$'
|
|
eval_func = eval_register_arg
|
|
elif re.match(r'^cr[A-Z]$', pat):
|
|
regex = r'^cr([0-7])$'
|
|
eval_func = eval_register_arg
|
|
else:
|
|
regex = r'^[\w' + re.escape('()+-*/%|&~^') + r']+$'
|
|
eval_func = eval_expression
|
|
|
|
validation_list.append((regex, eval_func))
|
|
|
|
# Check the regex, apply the evaluation
|
|
final_args = []
|
|
for arg, (regex, eval_func) in zip(args, validation_list):
|
|
m = re.match(regex, arg)
|
|
if not m: raise SyntaxError('bad argument')
|
|
|
|
try:
|
|
final_args.append(eval_func(arg))
|
|
except:
|
|
raise SyntaxError('bad argument')
|
|
|
|
return func(*final_args)
|
|
|
|
|
|
def _b(value, startbit, endbit=None):
|
|
if endbit is None: endbit = startbit
|
|
numbits = endbit + 1 - startbit
|
|
mask = (1 << numbits) - 1
|
|
shift = 31 - endbit
|
|
return (value & mask) << shift
|
|
|
|
|
|
def command_line():
|
|
parser = argparse.ArgumentParser(description='''
|
|
Assemble PowerPC assembly code into a raw binary. Supports instructions, labels: and #comments.
|
|
''')
|
|
|
|
parser.add_argument('src', metavar='ASSEMBLY', nargs='?', action='store', help='PowerPC assembly code (stdin if omitted)')
|
|
parser.add_argument('-o', dest='dest', metavar='BINARY', action='store', help='Raw PowerPC binary (stdout if omitted)')
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.src is None:
|
|
asm = sys.stdin.read()
|
|
else:
|
|
with open(args.src) as f:
|
|
asm = f.read()
|
|
|
|
binary = assemble(asm)
|
|
|
|
if args.dest is None:
|
|
sys.stdout.buffer.write(binary)
|
|
else:
|
|
with open(args.dest, 'wb') as f:
|
|
af.write(binary)
|
|
|
|
# All supported instructions, alphabetically
|
|
|
|
def inst_add(dot, rD, rA, rB):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(266,22,30)|_b(dot,31)
|
|
|
|
def inst_addis(rD, rA, simm):
|
|
return _b(15,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(simm,16,31)
|
|
|
|
def inst_addi(rD, rA0, simm):
|
|
return _b(14,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(simm,16,31)
|
|
|
|
def inst_and(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(28,21,30)|_b(dot,31)
|
|
|
|
def inst_andc(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(60,21,30)|_b(dot,31)
|
|
|
|
def inst_andi(dot, rA, rS, uimm):
|
|
if not dot: raise SyntaxError('dot required')
|
|
return _b(28,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(uimm,16,31)
|
|
|
|
def inst_andis(dot, rA, rS, uimm):
|
|
if not dot: raise SyntaxError('dot required')
|
|
return _b(29,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(uimm,16,31)
|
|
|
|
def inst_b(link, bd):
|
|
if bd & 3: raise SyntaxError('branch target not 4-aligned')
|
|
return _b(18,0,5)|_b(bd>>2,6,29)|_b(link,31)
|
|
|
|
def inst_bc(link, bo, bi, bd):
|
|
if bd & 3: raise SyntaxError('branch target not 4-aligned')
|
|
return _b(16,0,5)|_b(bo,6,10)|_b(bi,11,15)|_b(bd>>2,16,29)|_b(link,31)
|
|
|
|
def inst_bcctr(link, bo, bi):
|
|
return _b(19,0,5)|_b(bo,6,10)|_b(bi,11,15)|_b(528,21,30)|_b(link,31)
|
|
|
|
def inst_bclr(link, bo, bi):
|
|
return _b(19,0,5)|_b(bo,6,10)|_b(bi,11,15)|_b(16,21,30)|_b(link,31)
|
|
|
|
def inst_cmpw(crD_optional, rA, rB):
|
|
return _b(31,0,5)|_b(crD_optional,6,8)|_b(rA,11,15)|_b(rB,16,20)
|
|
|
|
def inst_cmpwi(crD_optional, rA, simm):
|
|
return _b(11,0,5)|_b(crD_optional,6,8)|_b(rA,11,15)|_b(simm,16,31)
|
|
|
|
def inst_cmplw(crD_optional, rA, rB):
|
|
return _b(31,0,5)|_b(crD_optional,6,8)|_b(rA,11,15)|_b(rB,16,20)|b(32,21,30)
|
|
|
|
def inst_cmplwi(crD_optional, rA, simm):
|
|
return _b(10,0,5)|_b(crD_optional,6,8)|_b(rA,11,15)|_b(simm,16,31)
|
|
|
|
def inst_crand(crbD, crbA, crbB):
|
|
return _b(19,0,5)|_b(crbD,6,10)|_b(crbA,11,15)|_b(crbB,16,20)|_b(257,21,30)
|
|
|
|
def inst_crandc(crbD, crbA, crbB):
|
|
return _b(19,0,5)|_b(crbD,6,10)|_b(crbA,11,15)|_b(crbB,16,20)|_b(129,21,30)
|
|
|
|
def inst_creqv(crbD, crbA, crbB):
|
|
return _b(19,0,5)|_b(crbD,6,10)|_b(crbA,11,15)|_b(crbB,16,20)|_b(289,21,30)
|
|
|
|
def inst_crnand(crbD, crbA, crbB):
|
|
return _b(19,0,5)|_b(crbD,6,10)|_b(crbA,11,15)|_b(crbB,16,20)|_b(225,21,30)
|
|
|
|
def inst_crnor(crbD, crbA, crbB):
|
|
return _b(19,0,5)|_b(crbD,6,10)|_b(crbA,11,15)|_b(crbB,16,20)|_b(33,21,30)
|
|
|
|
def inst_cror(crbD, crbA, crbB):
|
|
return _b(19,0,5)|_b(crbD,6,10)|_b(crbA,11,15)|_b(crbB,16,20)|_b(449,21,30)
|
|
|
|
def inst_crorc(crbD, crbA, crbB):
|
|
return _b(19,0,5)|_b(crbD,6,10)|_b(crbA,11,15)|_b(crbB,16,20)|_b(417,21,30)
|
|
|
|
def inst_crxor(crbD, crbA, crbB):
|
|
return _b(19,0,5)|_b(crbD,6,10)|_b(crbA,11,15)|_b(crbB,16,20)|_b(193,21,30)
|
|
|
|
def inst_eqv(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(284,21,30)|_b(dot,31)
|
|
|
|
def inst_extsb(dot, rA, rS):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(954,21,30)|_b(dot,31)
|
|
|
|
def inst_extsh(dot, rA, rS):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(922,21,30)|_b(dot,31)
|
|
|
|
def inst_lbz(rD, d_bracket, rA0):
|
|
return _b(34,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_lbzu(rD, d_bracket, rA):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
if rA == rD: raise SyntaxError('rA = rD')
|
|
return _b(35,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_lbzux(rD, rA, rB):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
if rA == rD: raise SyntaxError('rA = rD')
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(119,21,30)
|
|
|
|
def inst_lbzx(rD, rA0, rB):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(rB,16,20)|_b(87,21,30)
|
|
|
|
def inst_lha(rD, d_bracket, rA0):
|
|
return _b(42,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_lhau(rD, d_bracket, rA):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
if rA == rD: raise SyntaxError('rA = rD')
|
|
return _b(43,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_lhaux(rD, rA, rB):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
if rA == rD: raise SyntaxError('rA = rD')
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(375,21,30)
|
|
|
|
def inst_lhax(rD, rA0, rB):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(rB,16,20)|_b(343,21,30)
|
|
|
|
def inst_lha(rD, d_bracket, rA0):
|
|
return _b(40,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_lhzu(rD, d_bracket, rA):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
if rA == rD: raise SyntaxError('rA = rD')
|
|
return _b(41,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_lhzux(rD, rA, rB):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
if rA == rD: raise SyntaxError('rA = rD')
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(311,21,30)
|
|
|
|
def inst_lhzx(rD, rA0, rB):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(rB,16,20)|_b(279,21,30)
|
|
|
|
def inst_lmw(rD, d_bracket, rA0):
|
|
return _b(46,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_lwz(rD, d_bracket, rA0):
|
|
return _b(32,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_lwzu(rD, d_bracket, rA):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
if rA == rD: raise SyntaxError('rA = rD')
|
|
return _b(33,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_lwzux(rD, rA, rB):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
if rA == rD: raise SyntaxError('rA = rD')
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(55,21,30)
|
|
|
|
def inst_lwzx(rD, rA0, rB):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA0,11,15)|_b(rB,16,20)|_b(23,21,30)
|
|
|
|
def inst_mcrf(crD, crS):
|
|
return _b(19,0,5)|_b(crD,6,8)|_b(crS,11,13)
|
|
|
|
def inst_mfcr(rD):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(19,21,30)
|
|
|
|
def inst_mfspr(rD, spr):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(spr&0x1f,11,15)|_b(spr>>5,16,20)|_b(339,21,30)
|
|
|
|
def inst_mtcrf(crm, rS):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(crm,12,19)|_b(144,21,30)
|
|
|
|
def inst_mtspr(rS, spr):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(spr&0x1f,11,15)|_b(spr>>5,16,20)|_b(467,21,30)
|
|
|
|
def inst_mulhw(dot, rD, rA, rB):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(75,22,30)|_b(dot,31)
|
|
|
|
def inst_mulhwu(dot, rD, rA, rB):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(11,22,30)|_b(dot,31)
|
|
|
|
def inst_nand(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(476,21,30)|_b(dot,31)
|
|
|
|
def inst_neg(dot, rD, rA):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(104,22,30)|_b(dot,31)
|
|
|
|
def inst_nor(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(124,21,30)|_b(dot,31)
|
|
|
|
def inst_or(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(444,21,30)|_b(dot,31)
|
|
|
|
def inst_orc(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(412,21,30)|_b(dot,31)
|
|
|
|
def inst_orc(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(412,21,30)|_b(dot,31)
|
|
|
|
def inst_ori(rA, rS, uimm):
|
|
return _b(24,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(uimm,16,31)
|
|
|
|
def inst_oris(rA, rS, uimm):
|
|
return _b(25,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(uimm,16,31)
|
|
|
|
def inst_rlwimi(dot, rA, rS, sh, mb, me):
|
|
return _b(20,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(sh,16,20)|_b(mb,21,25)|_b(me,26,30)|_b(dot,31)
|
|
|
|
def inst_rlwinm(dot, rA, rS, sh, mb, me):
|
|
return _b(21,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(sh,16,20)|_b(mb,21,25)|_b(me,26,30)|_b(dot,31)
|
|
|
|
def inst_rlwnm(dot, rA, rS, rB, mb, me):
|
|
return _b(23,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(mb,21,25)|_b(me,26,30)|_b(dot,31)
|
|
|
|
def inst_slw(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(24,21,30)|_b(dot,31)
|
|
|
|
def inst_sraw(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(792,21,30)|_b(dot,31)
|
|
|
|
def inst_srawi(dot, rA, rS, sh):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(sh,16,20)|_b(824,21,30)|_b(dot,31)
|
|
|
|
def inst_srw(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(536,21,30)|_b(dot,31)
|
|
|
|
def inst_stb(rS, d_bracket, rA0):
|
|
return _b(38,0,5)|_b(rS,6,10)|_b(rA0,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_stbu(rS, d_bracket, rA):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
return _b(29,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_stbux(rS, rA, rB):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(247,21,30)
|
|
|
|
def inst_stbx(rS, rA0, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA0,11,15)|_b(rB,16,20)|_b(215,21,30)
|
|
|
|
def inst_sth(rS, d_bracket, rA0):
|
|
return _b(44,0,5)|_b(rS,6,10)|_b(rA0,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_sthu(rS, d_bracket, rA):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
return _b(45,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_sthux(rS, rA, rB):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(439,21,30)
|
|
|
|
def inst_sthx(rS, rA0, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA0,11,15)|_b(rB,16,20)|_b(407,21,30)
|
|
|
|
def inst_stmw(rS, d_bracket, rA0):
|
|
return _b(47,0,5)|_b(rS,6,10)|_b(rA0,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_stw(rS, d_bracket, rA0):
|
|
return _b(36,0,5)|_b(rS,6,10)|_b(rA0,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_stwu(rS, d_bracket, rA):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
return _b(37,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(d_bracket,16,31)
|
|
|
|
def inst_stwux(rS, rA, rB):
|
|
if rA == 0: raise SyntaxError('rA = 0')
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(183,21,30)
|
|
|
|
def inst_stwx(rS, rA0, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA0,11,15)|_b(rB,16,20)|_b(151,21,30)
|
|
|
|
def inst_subf(dot, rD, rA, rB):
|
|
return _b(31,0,5)|_b(rD,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(40,22,30)|_b(dot,31)
|
|
|
|
def inst_xor(dot, rA, rS, rB):
|
|
return _b(31,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(rB,16,20)|_b(316,21,30)|_b(dot,31)
|
|
|
|
def inst_xori(rA, rS, uimm):
|
|
return _b(26,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(uimm,16,31)
|
|
|
|
def inst_xoris(rA, rS, uimm):
|
|
return _b(27,0,5)|_b(rS,6,10)|_b(rA,11,15)|_b(uimm,16,31)
|
|
|
|
# "High-level" instructions
|
|
|
|
def inst_bctr(link):
|
|
return inst_bcctr(link, 0b10100, 0)
|
|
|
|
def inst_blr(link):
|
|
return inst_bclr(link, 0b10100, 0)
|
|
|
|
def inst_beq(link, crA_optional, dest):
|
|
return inst_bc(link, 0b01100, 4*crA_optional+2, dest)
|
|
|
|
def inst_bge(link, crA_optional, dest):
|
|
return inst_bc(link, 0b01100, 4*crA_optional, dest)
|
|
|
|
def inst_bgt(link, crA_optional, dest):
|
|
return inst_bc(link, 0b00100, 4*crA_optional+1, dest)
|
|
|
|
def inst_ble(link, crA_optional, dest):
|
|
return inst_bc(link, 0b01100, 4*crA_optional+1, dest)
|
|
|
|
def inst_blt(link, crA_optional, dest):
|
|
return inst_bc(link, 0b00100, 4*crA_optional, dest)
|
|
|
|
def inst_bne(link, crA_optional, dest):
|
|
return inst_bc(link, 0b00100, 4*crA_optional+2, dest)
|
|
|
|
def inst_crclr(crbD):
|
|
return inst_crxor(crbD, crbD, crbD)
|
|
|
|
def inst_crset(crbD):
|
|
return inst_creqv(crbD, crbD, crbD)
|
|
|
|
def inst_li(rD, simm):
|
|
return inst_addi(rD, 0, simm)
|
|
|
|
def inst_lis(rD, simm):
|
|
return inst_addis(rD, 0, simm)
|
|
|
|
def inst_mfctr(rD):
|
|
return inst_mfspr(rD, 9)
|
|
|
|
def inst_mflr(rD):
|
|
return inst_mfspr(rD, 8)
|
|
|
|
def inst_mfxer(rD):
|
|
return inst_mfspr(rD, 1)
|
|
|
|
def inst_mtctr(rD):
|
|
return inst_mtspr(rD, 9)
|
|
|
|
def inst_mtlr(rD):
|
|
return inst_mtspr(rD, 8)
|
|
|
|
def inst_mtxer(rD):
|
|
return inst_mtspr(rD, 1)
|
|
|
|
def inst_nop():
|
|
return inst_ori(0, 0, 0)
|
|
|
|
def inst_subi(rD, rA, simm):
|
|
return inst_addi(rD, rA, -simm)
|
|
|
|
# Command line needs to go dead last
|
|
if __name__ == '__main__': command_line()
|