+# Move between CRs. 3 bits for destination, 3 bits for source in
+# 16-bit mode. That covers all possibilities. For 10-bit mode, only
+# 2 bits for destination.
+def mcrfop(opcode, ops):
+ if rccregs2(ops[0]):
+ return 3
+ return 1
+# Logical ops between two CRs into one. 2 bits for destination, that
+# must coincide with one of the inputs, 3 bits for the other input.
+# 16-bit only.
+def crops(opcode, ops):
+ if rccregs2(ops[0]) and regno(ops[0]) is regno(ops[1]):
+ return 1
+ return 0
+
+# 3 bits for general-purpose register; immediate identifies the
+# special purpose register to move to: 8 for lr, 9 for ctr. 16-bit
+# only. mtspr imm,rN moves from rN to the spr; mfspr rN,imm moves
+# from spr to rN.
+def mtsprops(opcode, ops):
+ if immval(ops[0]) in (8, 9) and rcregs3(ops[1]):
+ return 1
+ return 0
+def mfsprops(opcode, ops):
+ if immval(ops[1]) in (8, 9) and rcregs3(ops[0]):
+ return 1
+ return 0
+
+# 3 bits for nonzero general-purpose register; the immediate is a
+# per-CR mask (8-bits). mtcr rN is mtcrf 0xFF, rN. mfcr rN is a raw
+# opcode, not an alias.
+def mtcrfops(opcode, ops):
+ if immval(ops[0]) is 255 and rcregs3(ops[1]) and regno(ops[1]) is not 0:
+ return 1
+ return 0
+def mfcrops(opcode, ops):
+ if rcregs3(ops[0]) and regno(ops[0]) is not 0:
+ return 1
+ return 0
+
+# 3 bits for destination and source register, must be the same. Full
+# shift range fits. 16-imm format.
+def shiftops(opcode, ops):
+ if rcregs3(ops[0]) and regno(ops[0]) is regno(ops[1]):
+ return 2
+ return 0
+
+# For 16-imm 'addis' and 'addi', we have 3 bits (nonzero) for the
+# destination register, source register is implied 0, the immediate
+# must either fit in signed 5-bit, left-shifted by 3, or in signed
+# 7-bit without shift. ??? That seems backwards.
+def addiops(opcode, ops):
+ if rcregs3(ops[0]) and regno(ops[0]) is not 0 \
+ and regno(ops[1]) is 0 and imm8(ops[2]) \
+ and immbits(ops[2]) <= 8 \
+ and ((immval(ops[2]) & 7) is 0 or immbits(ops[2]) <= 7):
+ return 2
+ return maybenop(opcode, ops)
+
+# cmpdi and cmpwi are aliases to uncompressed cmp CR#, L, RA, imm16,
+# CR# being the target condition register, L being set for d rather
+# than w. In 16-imm, CR# must be zero, RA must fit in 3 bits, and the
+# immediate must be 6 bits signed.
+def cmpiops(opcode, ops):
+ if regno(ops[0]) is 0 and immval(ops[1]) in (0,1) \
+ and rcregs3(ops[2]) and immbits(ops[3]) <= 6:
+ return 2
+ return 0
+
+# 16-imm bc, with or without LK, uses 3 bits for BI (CR0 and CR1 only),
+# and 1 bit for BO1 (to tell BO 12 from negated 4).
+def bcops(opcode, ops):
+ if immval(ops[0]) in (4,12) and regno(crbtreg(ops[1])) <= 1 \
+ and immbits(ops[2]) <= 8:
+ return 2
+ return 0
+
+# 2 bits for BI and 3 bits for BO in 10-bit encoding; one extra bit
+# for each in 16-bit.
+def bclrops(opcode, ops):
+ if immval(ops[0]) <= 15 and regno(crbtreg(ops[1])) <= 1 \
+ and immbits(ops[2]) is 0:
+ if immval(ops[0]) <= 7 and regno(crbtreg(ops[1])) is 0:
+ return 3
+ return 1
+ return 0
+