// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-package ppc64
+package mips
import (
"cmd/internal/obj"
- "encoding/binary"
"fmt"
"log"
"sort"
a1 uint8
a2 uint8
a3 uint8
- a4 uint8
type_ int8
size int8
param int16
}
var optab = []Optab{
- Optab{obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
- Optab{obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
- Optab{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
- Optab{obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
- /* move register */
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},
- Optab{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
- Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
- Optab{AADD, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
- Optab{AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
- Optab{AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
- Optab{AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
- Optab{AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0},
- Optab{AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
- Optab{AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
- Optab{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
- Optab{AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
- Optab{AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
- Optab{AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
- Optab{AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
- Optab{AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
- Optab{AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
- Optab{AAND, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, no literal */
- Optab{AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
- Optab{AANDCC, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
- Optab{AANDCC, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
- Optab{AANDCC, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
- Optab{AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
- Optab{AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
- Optab{AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
- Optab{AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
- Optab{AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
- Optab{AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
- Optab{AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
- Optab{AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
- Optab{AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
- Optab{AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
- Optab{AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
- Optab{AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
- Optab{AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
- Optab{ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0},
- Optab{ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
- Optab{ASUBC, C_REG, C_NONE, C_ADDCON, C_REG, 27, 4, 0},
- Optab{ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 12, 0},
- Optab{AOR, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, literal not cc (or/xor) */
- Optab{AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
- Optab{AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
- Optab{AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
- Optab{AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
- Optab{AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
- Optab{AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
- Optab{AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
- Optab{ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */
- Optab{ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
- Optab{ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, /* op r2[,r1],r3 */
- Optab{ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
- Optab{ASLW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
- Optab{ASLW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
- Optab{ASLD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
- Optab{ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
- Optab{ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0},
- Optab{ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0},
- Optab{ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0},
- Optab{ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0},
- Optab{ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
- Optab{ASRAW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
- Optab{ASRAW, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
- Optab{ASRAW, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
- Optab{ASRAD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
- Optab{ASRAD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
- Optab{ASRAD, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
- Optab{ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
- Optab{ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0},
- Optab{ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0},
- Optab{ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0},
- Optab{ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
- Optab{ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
- Optab{ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
- Optab{ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0},
- Optab{AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0},
- Optab{AFADD, C_FREG, C_REG, C_NONE, C_FREG, 2, 4, 0},
- Optab{AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
- Optab{AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 4, 0},
- Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
- Optab{AFMADD, C_FREG, C_REG, C_FREG, C_FREG, 34, 4, 0},
- Optab{AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 4, 0},
- Optab{AFMUL, C_FREG, C_REG, C_NONE, C_FREG, 32, 4, 0},
-
- /* store, short offset */
- Optab{AMOVD, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
- Optab{AMOVW, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
- Optab{AMOVWZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
- Optab{AMOVBZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
- Optab{AMOVBZU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
- Optab{AMOVB, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
- Optab{AMOVBU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
- Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
- Optab{AMOVB, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
- Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
- Optab{AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
- Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
- Optab{AMOVBZU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
- Optab{AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
- Optab{AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
-
- /* load, short offset */
- Optab{AMOVD, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVW, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVWZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVBZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVBZU, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVB, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
- Optab{AMOVBU, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
- Optab{AMOVD, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
- Optab{AMOVW, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
- Optab{AMOVWZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
- Optab{AMOVBZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
- Optab{AMOVB, C_SEXT, C_NONE, C_NONE, C_REG, 9, 8, REGSB},
- Optab{AMOVD, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
- Optab{AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
- Optab{AMOVWZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
- Optab{AMOVBZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
- Optab{AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, 9, 8, REGSP},
- Optab{AMOVD, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVWZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVBZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVBZU, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
- Optab{AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
- Optab{AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
-
- /* store, long offset */
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
- Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
- Optab{AMOVB, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
- Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
- Optab{AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
- Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
- Optab{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
- Optab{AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
- Optab{AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
-
- /* load, long offset */
- Optab{AMOVD, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
- Optab{AMOVW, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
- Optab{AMOVWZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
- Optab{AMOVBZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
- Optab{AMOVB, C_LEXT, C_NONE, C_NONE, C_REG, 37, 12, REGSB},
- Optab{AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
- Optab{AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
- Optab{AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
- Optab{AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
- Optab{AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 37, 12, REGSP},
- Optab{AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
- Optab{AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
- Optab{AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
- Optab{AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
- Optab{AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 37, 12, REGZERO},
- Optab{AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
- Optab{AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
- Optab{AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
- Optab{AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
- Optab{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0},
-
- /* load constant */
- Optab{AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB},
- Optab{AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
- Optab{AMOVD, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
- Optab{AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
- Optab{AMOVD, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
- Optab{AMOVW, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
- Optab{AMOVW, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
- Optab{AMOVW, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
- Optab{AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
- Optab{AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
- Optab{AMOVWZ, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
- Optab{AMOVWZ, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
- Optab{AMOVWZ, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
- Optab{AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
- Optab{AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
-
- /* load unsigned/long constants (TO DO: check) */
- Optab{AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
- Optab{AMOVD, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
- Optab{AMOVW, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
- Optab{AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
- Optab{AMOVWZ, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
- Optab{AMOVWZ, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
- Optab{AMOVHBR, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
- Optab{AMOVHBR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
- Optab{AMOVHBR, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
- Optab{AMOVHBR, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
- Optab{ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0},
- Optab{ASYSCALL, C_REG, C_NONE, C_NONE, C_NONE, 77, 12, 0},
- Optab{ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 12, 0},
- Optab{ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
- Optab{ABEQ, C_CREG, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
- Optab{ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
- Optab{ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0},
- Optab{ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0},
- Optab{ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0},
- Optab{ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0},
- Optab{ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0},
- Optab{ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
- Optab{ABC, C_NONE, C_REG, C_NONE, C_LR, 18, 4, 0},
- Optab{ABC, C_NONE, C_REG, C_NONE, C_CTR, 18, 4, 0},
- Optab{ABC, C_SCON, C_REG, C_NONE, C_LR, 18, 4, 0},
- Optab{ABC, C_SCON, C_REG, C_NONE, C_CTR, 18, 4, 0},
- Optab{ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
- Optab{AFMOVD, C_SEXT, C_NONE, C_NONE, C_FREG, 8, 4, REGSB},
- Optab{AFMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, 8, 4, REGSP},
- Optab{AFMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, 8, 4, REGZERO},
- Optab{AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB},
- Optab{AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP},
- Optab{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO},
- Optab{AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0},
- Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
- Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
- Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
- Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
- Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
- Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
- Optab{AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
- Optab{ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
- Optab{AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0},
- Optab{ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
- Optab{ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
- Optab{AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
- Optab{AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0},
- Optab{AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0},
- Optab{ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
- Optab{ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0},
- Optab{AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0},
- Optab{AREM, C_REG, C_REG, C_NONE, C_REG, 50, 12, 0},
- Optab{AREMU, C_REG, C_NONE, C_NONE, C_REG, 50, 16, 0},
- Optab{AREMU, C_REG, C_REG, C_NONE, C_REG, 50, 16, 0},
- Optab{AREMD, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
- Optab{AREMD, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
- Optab{AREMDU, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
- Optab{AREMDU, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
- Optab{AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0},
- Optab{AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0},
- Optab{AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0},
- Optab{AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0},
- Optab{AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0},
- Optab{AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0}, /* mfmsr */
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsrd */
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */
-
- /* 64-bit special registers */
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0},
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
- Optab{AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
- Optab{AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
- Optab{AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0},
- Optab{AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0},
- Optab{AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
-
- /* 32-bit special registers (gloss over sign-extension or not?) */
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
- Optab{AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
- Optab{AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
- Optab{AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
- Optab{AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
- Optab{AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0},
- Optab{AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0},
- Optab{AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
- Optab{AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
- Optab{AMOVFL, C_REG, C_NONE, C_LCON, C_CREG, 69, 4, 0},
- Optab{AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
- Optab{AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
- Optab{AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
- Optab{ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
- Optab{ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
- Optab{ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0},
- Optab{ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0},
- Optab{ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
- Optab{ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
- Optab{ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0},
- Optab{ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0},
- Optab{AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0},
- Optab{AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0},
- Optab{ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0},
- Optab{ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0},
- Optab{ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
- Optab{ADCBF, C_ZOREG, C_REG, C_NONE, C_NONE, 43, 4, 0},
- Optab{AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
- Optab{AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
- Optab{AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
- Optab{AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
- Optab{AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
- Optab{ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
- Optab{ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},
- Optab{ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
- Optab{ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
- Optab{ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
- Optab{ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
- Optab{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
- Optab{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
- Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
- Optab{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0},
- Optab{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
- Optab{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
- Optab{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
- Optab{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
- Optab{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
-
- Optab{obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
+ {obj.ATEXT, C_LEXT, C_NONE, C_TEXTSIZE, 0, 0, 0},
+ {obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0},
+
+ {AMOVW, C_REG, C_NONE, C_REG, 14, 8, 0},
+ {AMOVV, C_REG, C_NONE, C_REG, 1, 4, 0},
+ {AMOVB, C_REG, C_NONE, C_REG, 12, 8, 0},
+ {AMOVBU, C_REG, C_NONE, C_REG, 13, 4, 0},
+ {AMOVWU, C_REG, C_NONE, C_REG, 14, 8, 0},
+
+ {ASUB, C_REG, C_REG, C_REG, 2, 4, 0},
+ {AADD, C_REG, C_REG, C_REG, 2, 4, 0},
+ {AAND, C_REG, C_REG, C_REG, 2, 4, 0},
+ {ASUB, C_REG, C_NONE, C_REG, 2, 4, 0},
+ {AADD, C_REG, C_NONE, C_REG, 2, 4, 0},
+ {AAND, C_REG, C_NONE, C_REG, 2, 4, 0},
+
+ {ASLL, C_REG, C_NONE, C_REG, 9, 4, 0},
+ {ASLL, C_REG, C_REG, C_REG, 9, 4, 0},
+
+ {AADDF, C_FREG, C_NONE, C_FREG, 32, 4, 0},
+ {AADDF, C_FREG, C_REG, C_FREG, 32, 4, 0},
+ {ACMPEQF, C_FREG, C_REG, C_NONE, 32, 4, 0},
+ {AABSF, C_FREG, C_NONE, C_FREG, 33, 4, 0},
+ {AMOVF, C_FREG, C_NONE, C_FREG, 33, 4, 0},
+ {AMOVD, C_FREG, C_NONE, C_FREG, 33, 4, 0},
+
+ {AMOVW, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
+ {AMOVWU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
+ {AMOVV, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
+ {AMOVB, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
+ {AMOVBU, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
+ {AMOVWL, C_REG, C_NONE, C_SEXT, 7, 4, REGSB},
+ {AMOVW, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
+ {AMOVWU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
+ {AMOVV, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
+ {AMOVB, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
+ {AMOVBU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
+ {AMOVWL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
+ {AMOVW, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
+ {AMOVWU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
+ {AMOVV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
+ {AMOVB, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
+ {AMOVBU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
+ {AMOVWL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
+
+ {AMOVW, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
+ {AMOVWU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
+ {AMOVV, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
+ {AMOVB, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
+ {AMOVBU, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
+ {AMOVWL, C_SEXT, C_NONE, C_REG, 8, 4, REGSB},
+ {AMOVW, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
+ {AMOVWU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
+ {AMOVV, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
+ {AMOVB, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
+ {AMOVBU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
+ {AMOVWL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP},
+ {AMOVW, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
+ {AMOVWU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
+ {AMOVV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
+ {AMOVB, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
+ {AMOVBU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
+ {AMOVWL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO},
+
+ {AMOVW, C_REG, C_NONE, C_LEXT, 35, 16, REGSB},
+ {AMOVWU, C_REG, C_NONE, C_LEXT, 35, 16, REGSB},
+ {AMOVV, C_REG, C_NONE, C_LEXT, 35, 16, REGSB},
+ {AMOVB, C_REG, C_NONE, C_LEXT, 35, 16, REGSB},
+ {AMOVBU, C_REG, C_NONE, C_LEXT, 35, 16, REGSB},
+ {AMOVW, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP},
+ {AMOVWU, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP},
+ {AMOVV, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP},
+ {AMOVB, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP},
+ {AMOVBU, C_REG, C_NONE, C_LAUTO, 35, 16, REGSP},
+ {AMOVW, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO},
+ {AMOVWU, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO},
+ {AMOVV, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO},
+ {AMOVB, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO},
+ {AMOVBU, C_REG, C_NONE, C_LOREG, 35, 16, REGZERO},
+ {AMOVW, C_REG, C_NONE, C_ADDR, 50, 12, 0},
+ {AMOVWU, C_REG, C_NONE, C_ADDR, 50, 12, 0},
+ {AMOVV, C_REG, C_NONE, C_ADDR, 50, 12, 0},
+ {AMOVB, C_REG, C_NONE, C_ADDR, 50, 12, 0},
+ {AMOVBU, C_REG, C_NONE, C_ADDR, 50, 12, 0},
+
+ {AMOVW, C_LEXT, C_NONE, C_REG, 36, 16, REGSB},
+ {AMOVWU, C_LEXT, C_NONE, C_REG, 36, 16, REGSB},
+ {AMOVV, C_LEXT, C_NONE, C_REG, 36, 16, REGSB},
+ {AMOVB, C_LEXT, C_NONE, C_REG, 36, 16, REGSB},
+ {AMOVBU, C_LEXT, C_NONE, C_REG, 36, 16, REGSB},
+ {AMOVW, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP},
+ {AMOVWU, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP},
+ {AMOVV, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP},
+ {AMOVB, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP},
+ {AMOVBU, C_LAUTO, C_NONE, C_REG, 36, 16, REGSP},
+ {AMOVW, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO},
+ {AMOVWU, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO},
+ {AMOVV, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO},
+ {AMOVB, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO},
+ {AMOVBU, C_LOREG, C_NONE, C_REG, 36, 16, REGZERO},
+ {AMOVW, C_ADDR, C_NONE, C_REG, 51, 12, 0},
+ {AMOVWU, C_ADDR, C_NONE, C_REG, 51, 12, 0},
+ {AMOVV, C_ADDR, C_NONE, C_REG, 51, 12, 0},
+ {AMOVB, C_ADDR, C_NONE, C_REG, 51, 12, 0},
+ {AMOVBU, C_ADDR, C_NONE, C_REG, 51, 12, 0},
+
+ {AMOVW, C_SECON, C_NONE, C_REG, 3, 4, REGSB},
+ {AMOVV, C_SECON, C_NONE, C_REG, 3, 4, REGSB},
+ {AMOVW, C_SACON, C_NONE, C_REG, 3, 4, REGSP},
+ {AMOVV, C_SACON, C_NONE, C_REG, 3, 4, REGSP},
+ {AMOVW, C_LECON, C_NONE, C_REG, 26, 12, REGSB},
+ {AMOVV, C_LECON, C_NONE, C_REG, 26, 12, REGSB},
+ {AMOVW, C_LACON, C_NONE, C_REG, 26, 12, REGSP},
+ {AMOVV, C_LACON, C_NONE, C_REG, 26, 12, REGSP},
+ {AMOVW, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO},
+ {AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO},
+ {AMOVW, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO},
+ {AMOVV, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO},
+
+ {AMOVW, C_UCON, C_NONE, C_REG, 24, 4, 0},
+ {AMOVV, C_UCON, C_NONE, C_REG, 24, 4, 0},
+ {AMOVW, C_LCON, C_NONE, C_REG, 19, 8, 0},
+ {AMOVV, C_LCON, C_NONE, C_REG, 19, 8, 0},
+
+ {AMOVW, C_HI, C_NONE, C_REG, 20, 4, 0},
+ {AMOVV, C_HI, C_NONE, C_REG, 20, 4, 0},
+ {AMOVW, C_LO, C_NONE, C_REG, 20, 4, 0},
+ {AMOVV, C_LO, C_NONE, C_REG, 20, 4, 0},
+ {AMOVW, C_REG, C_NONE, C_HI, 21, 4, 0},
+ {AMOVV, C_REG, C_NONE, C_HI, 21, 4, 0},
+ {AMOVW, C_REG, C_NONE, C_LO, 21, 4, 0},
+ {AMOVV, C_REG, C_NONE, C_LO, 21, 4, 0},
+
+ {AMUL, C_REG, C_REG, C_NONE, 22, 4, 0},
+
+ {AADD, C_ADD0CON, C_REG, C_REG, 4, 4, 0},
+ {AADD, C_ADD0CON, C_NONE, C_REG, 4, 4, 0},
+ {AADD, C_ANDCON, C_REG, C_REG, 10, 8, 0},
+ {AADD, C_ANDCON, C_NONE, C_REG, 10, 8, 0},
+
+ {AAND, C_AND0CON, C_REG, C_REG, 4, 4, 0},
+ {AAND, C_AND0CON, C_NONE, C_REG, 4, 4, 0},
+ {AAND, C_ADDCON, C_REG, C_REG, 10, 8, 0},
+ {AAND, C_ADDCON, C_NONE, C_REG, 10, 8, 0},
+
+ {AADD, C_UCON, C_REG, C_REG, 25, 8, 0},
+ {AADD, C_UCON, C_NONE, C_REG, 25, 8, 0},
+ {AAND, C_UCON, C_REG, C_REG, 25, 8, 0},
+ {AAND, C_UCON, C_NONE, C_REG, 25, 8, 0},
+
+ {AADD, C_LCON, C_NONE, C_REG, 23, 12, 0},
+ {AAND, C_LCON, C_NONE, C_REG, 23, 12, 0},
+ {AADD, C_LCON, C_REG, C_REG, 23, 12, 0},
+ {AAND, C_LCON, C_REG, C_REG, 23, 12, 0},
+
+ {ASLL, C_SCON, C_REG, C_REG, 16, 4, 0},
+ {ASLL, C_SCON, C_NONE, C_REG, 16, 4, 0},
+
+ {ASYSCALL, C_NONE, C_NONE, C_NONE, 5, 4, 0},
+
+ {ABEQ, C_REG, C_REG, C_SBRA, 6, 4, 0},
+ {ABEQ, C_REG, C_NONE, C_SBRA, 6, 4, 0},
+ {ABLEZ, C_REG, C_NONE, C_SBRA, 6, 4, 0},
+ {ABFPT, C_NONE, C_NONE, C_SBRA, 6, 8, 0},
+
+ {AJMP, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
+ {AJAL, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
+
+ {AJMP, C_NONE, C_NONE, C_ZOREG, 18, 4, REGZERO},
+ {AJAL, C_NONE, C_NONE, C_ZOREG, 18, 4, REGLINK},
+
+ {AMOVW, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB},
+ {AMOVF, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB},
+ {AMOVD, C_SEXT, C_NONE, C_FREG, 27, 4, REGSB},
+ {AMOVW, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP},
+ {AMOVF, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP},
+ {AMOVD, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP},
+ {AMOVW, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO},
+ {AMOVF, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO},
+ {AMOVD, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO},
+
+ {AMOVW, C_LEXT, C_NONE, C_FREG, 27, 16, REGSB},
+ {AMOVF, C_LEXT, C_NONE, C_FREG, 27, 16, REGSB},
+ {AMOVD, C_LEXT, C_NONE, C_FREG, 27, 16, REGSB},
+ {AMOVW, C_LAUTO, C_NONE, C_FREG, 27, 16, REGSP},
+ {AMOVF, C_LAUTO, C_NONE, C_FREG, 27, 16, REGSP},
+ {AMOVD, C_LAUTO, C_NONE, C_FREG, 27, 16, REGSP},
+ {AMOVW, C_LOREG, C_NONE, C_FREG, 27, 16, REGZERO},
+ {AMOVF, C_LOREG, C_NONE, C_FREG, 27, 16, REGZERO},
+ {AMOVD, C_LOREG, C_NONE, C_FREG, 27, 16, REGZERO},
+ {AMOVF, C_ADDR, C_NONE, C_FREG, 51, 12, 0},
+ {AMOVD, C_ADDR, C_NONE, C_FREG, 51, 12, 0},
+
+ {AMOVW, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB},
+ {AMOVF, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB},
+ {AMOVD, C_FREG, C_NONE, C_SEXT, 28, 4, REGSB},
+ {AMOVW, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP},
+ {AMOVF, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP},
+ {AMOVD, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP},
+ {AMOVW, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO},
+ {AMOVF, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO},
+ {AMOVD, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO},
+
+ {AMOVW, C_FREG, C_NONE, C_LEXT, 28, 16, REGSB},
+ {AMOVF, C_FREG, C_NONE, C_LEXT, 28, 16, REGSB},
+ {AMOVD, C_FREG, C_NONE, C_LEXT, 28, 16, REGSB},
+ {AMOVW, C_FREG, C_NONE, C_LAUTO, 28, 16, REGSP},
+ {AMOVF, C_FREG, C_NONE, C_LAUTO, 28, 16, REGSP},
+ {AMOVD, C_FREG, C_NONE, C_LAUTO, 28, 16, REGSP},
+ {AMOVW, C_FREG, C_NONE, C_LOREG, 28, 16, REGZERO},
+ {AMOVF, C_FREG, C_NONE, C_LOREG, 28, 16, REGZERO},
+ {AMOVD, C_FREG, C_NONE, C_LOREG, 28, 16, REGZERO},
+ {AMOVF, C_FREG, C_NONE, C_ADDR, 50, 12, 0},
+ {AMOVD, C_FREG, C_NONE, C_ADDR, 50, 12, 0},
+
+ {AMOVW, C_REG, C_NONE, C_FREG, 30, 4, 0},
+ {AMOVW, C_FREG, C_NONE, C_REG, 31, 4, 0},
+ {AMOVV, C_REG, C_NONE, C_FREG, 47, 4, 0},
+ {AMOVV, C_FREG, C_NONE, C_REG, 48, 4, 0},
+
+ {AMOVW, C_ADDCON, C_NONE, C_FREG, 34, 8, 0},
+ {AMOVW, C_ANDCON, C_NONE, C_FREG, 34, 8, 0},
+ {AMOVW, C_UCON, C_NONE, C_FREG, 35, 8, 0},
+ {AMOVW, C_LCON, C_NONE, C_FREG, 36, 12, 0},
+
+ {AMOVW, C_REG, C_NONE, C_MREG, 37, 4, 0},
+ {AMOVV, C_REG, C_NONE, C_MREG, 37, 4, 0},
+ {AMOVW, C_MREG, C_NONE, C_REG, 38, 4, 0},
+ {AMOVV, C_MREG, C_NONE, C_REG, 38, 4, 0},
+
+ {AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0},
+
+ {AMOVW, C_REG, C_NONE, C_FCREG, 41, 8, 0},
+ {AMOVV, C_REG, C_NONE, C_FCREG, 41, 8, 0},
+ {AMOVW, C_FCREG, C_NONE, C_REG, 42, 4, 0},
+ {AMOVV, C_FCREG, C_NONE, C_REG, 42, 4, 0},
+
+ {ABREAK, C_REG, C_NONE, C_SEXT, 7, 4, REGSB}, /* really CACHE instruction */
+ {ABREAK, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP},
+ {ABREAK, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO},
+ {ABREAK, C_NONE, C_NONE, C_NONE, 5, 4, 0},
+
+ {obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0},
+ {obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0},
+ {obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0},
+ {obj.AFUNCDATA, C_SCON, C_NONE, C_ADDR, 0, 0, 0},
+ {obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0},
+ {obj.ADUFFZERO, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as AJMP
+ {obj.ADUFFCOPY, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as AJMP
+
+ {obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0},
}
type Oprang struct {
var xcmp [C_NCLASS][C_NCLASS]uint8
-func span9(ctxt *obj.Link, cursym *obj.LSym) {
+func span0(ctxt *obj.Link, cursym *obj.LSym) {
p := cursym.Text
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
return
ctxt.Cursym = cursym
ctxt.Autosize = int32(p.To.Offset + 8)
- if oprange[AANDN&obj.AMask].start == nil {
+ if oprange[AOR&obj.AMask].start == nil {
buildop(ctxt)
}
o = oplook(ctxt, p)
// very large conditional branches
- if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
+ if o.type_ == 6 && p.Pcond != nil {
otxt = p.Pcond.Pc - c
- if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
+ if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 {
q = ctxt.NewProg()
q.Link = p.Link
p.Link = q
- q.As = ABR
+ q.As = AJMP
+ q.Lineno = p.Lineno
q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Pcond
p.Pcond = q
q = ctxt.NewProg()
q.Link = p.Link
p.Link = q
- q.As = ABR
+ q.As = AJMP
+ q.Lineno = p.Lineno
q.To.Type = obj.TYPE_BRANCH
q.Pcond = q.Link.Link
- //addnop(p->link);
- //addnop(p);
+ addnop(ctxt, p.Link)
+ addnop(ctxt, p)
bflag = 1
}
}
bp := cursym.P
var i int32
- var out [6]uint32
+ var out [4]uint32
for p := cursym.Text.Link; p != nil; p = p.Link {
ctxt.Pc = p.Pc
ctxt.Curp = p
o = oplook(ctxt, p)
if int(o.size) > 4*len(out) {
- log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
+ log.Fatalf("out array in span0 is too small, need at least %d for %v", o.size/4, p)
}
asmout(ctxt, p, o, out[:])
for i = 0; i < int32(o.size/4); i++ {
if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
return C_FREG
}
- if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR {
- return C_CREG
+ if REG_M0 <= a.Reg && a.Reg <= REG_M31 {
+ return C_MREG
}
- if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
- switch a.Reg {
- case REG_LR:
- return C_LR
-
- case REG_XER:
- return C_XER
-
- case REG_CTR:
- return C_CTR
- }
-
- return C_SPR
+ if REG_FCR0 <= a.Reg && a.Reg <= REG_FCR31 {
+ return C_FCREG
}
-
- if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
- return C_SPR
- }
- if a.Reg == REG_FPSCR {
- return C_FPSCR
+ if a.Reg == REG_LO {
+ return C_LO
}
- if a.Reg == REG_MSR {
- return C_MSR
+ if a.Reg == REG_HI {
+ return C_HI
}
return C_GOK
case obj.TYPE_CONST,
obj.TYPE_ADDR:
switch a.Name {
- case obj.TYPE_NONE:
+ case obj.NAME_NONE:
ctxt.Instoffset = a.Offset
if a.Reg != 0 {
if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG {
if isint32(ctxt.Instoffset) || isuint32(uint64(ctxt.Instoffset)) {
return C_LCON
}
- return C_DCON
+ return C_LCON // C_DCON
}
if ctxt.Instoffset >= -0x8000 {
if isint32(ctxt.Instoffset) {
return C_LCON
}
- return C_DCON
+ return C_LCON // C_DCON
case obj.TYPE_BRANCH:
return C_SBRA
}
func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
+ if oprange[AOR&obj.AMask].start == nil {
+ buildop(ctxt)
+ }
+
a1 := int(p.Optab)
if a1 != 0 {
return &optab[a1-1:][0]
}
a1--
- a3 := C_NONE + 1
- if p.From3 != nil {
- a3 = int(p.From3.Class)
- if a3 == 0 {
- a3 = aclass(ctxt, p.From3) + 1
- p.From3.Class = int8(a3)
- }
+ a3 := int(p.To.Class)
+ if a3 == 0 {
+ a3 = aclass(ctxt, &p.To) + 1
+ p.To.Class = int8(a3)
}
a3--
- a4 := int(p.To.Class)
- if a4 == 0 {
- a4 = aclass(ctxt, &p.To) + 1
- p.To.Class = int8(a4)
- }
-
- a4--
a2 := C_NONE
if p.Reg != 0 {
a2 = C_REG
}
- //print("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4);
+ //print("oplook %P %d %d %d\n", p, a1, a2, a3);
r0 := p.As & obj.AMask
o := oprange[r0].start
e := oprange[r0].stop
c1 := xcmp[a1][:]
c3 := xcmp[a3][:]
- c4 := xcmp[a4][:]
for ; -cap(o) < -cap(e); o = o[1:] {
if int(o[0].a2) == a2 {
if c1[o[0].a1] != 0 {
if c3[o[0].a3] != 0 {
- if c4[o[0].a4] != 0 {
- p.Optab = uint16((-cap(o) + cap(optab)) + 1)
- return &o[0]
- }
+ p.Optab = uint16((-cap(o) + cap(optab)) + 1)
+ return &o[0]
}
}
}
}
- ctxt.Diag("illegal combination %v %v %v %v %v", obj.Aconv(int(p.As)), DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4))
+ ctxt.Diag("illegal combination %v %v %v %v", obj.Aconv(int(p.As)), DRconv(a1), DRconv(a2), DRconv(a3))
prasm(p)
if o == nil {
o = optab
return true
}
+ case C_ADD0CON:
+ if b == C_ADDCON {
+ return true
+ }
+ fallthrough
+
case C_ADDCON:
if b == C_ZCON || b == C_SCON {
return true
}
- case C_ANDCON:
- if b == C_ZCON || b == C_SCON {
+ case C_AND0CON:
+ if b == C_ANDCON {
return true
}
+ fallthrough
- case C_SPR:
- if b == C_LR || b == C_XER || b == C_CTR {
+ case C_ANDCON:
+ if b == C_ZCON || b == C_SCON {
return true
}
if b == C_ZOREG {
return true
}
-
- case C_ANY:
- return true
}
return false
if n != 0 {
return n < 0
}
- n = int(p1.a4) - int(p2.a4)
- if n != 0 {
- return n < 0
- }
return false
}
func opset(a, b0 int16) {
ctxt.Diag("unknown op in build: %v", obj.Aconv(int(r)))
log.Fatalf("bad code")
- case ADCBF: /* unary indexed: op (b+a); op (b) */
- opset(ADCBI, r0)
-
- opset(ADCBST, r0)
- opset(ADCBT, r0)
- opset(ADCBTST, r0)
- opset(ADCBZ, r0)
- opset(AICBI, r0)
-
- case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
- opset(ASTWCCC, r0)
-
- opset(ASTDCCC, r0)
-
- case AREM: /* macro */
- opset(AREMCC, r0)
-
- opset(AREMV, r0)
- opset(AREMVCC, r0)
-
- case AREMU:
- opset(AREMU, r0)
- opset(AREMUCC, r0)
- opset(AREMUV, r0)
- opset(AREMUVCC, r0)
-
- case AREMD:
- opset(AREMDCC, r0)
- opset(AREMDV, r0)
- opset(AREMDVCC, r0)
-
- case AREMDU:
- opset(AREMDU, r0)
- opset(AREMDUCC, r0)
- opset(AREMDUV, r0)
- opset(AREMDUVCC, r0)
-
- case ADIVW: /* op Rb[,Ra],Rd */
- opset(AMULHW, r0)
-
- opset(AMULHWCC, r0)
- opset(AMULHWU, r0)
- opset(AMULHWUCC, r0)
- opset(AMULLWCC, r0)
- opset(AMULLWVCC, r0)
- opset(AMULLWV, r0)
- opset(ADIVWCC, r0)
- opset(ADIVWV, r0)
- opset(ADIVWVCC, r0)
- opset(ADIVWU, r0)
- opset(ADIVWUCC, r0)
- opset(ADIVWUV, r0)
- opset(ADIVWUVCC, r0)
- opset(AADDCC, r0)
- opset(AADDCV, r0)
- opset(AADDCVCC, r0)
+ case AABSF:
+ opset(AMOVFD, r0)
+ opset(AMOVDF, r0)
+ opset(AMOVWF, r0)
+ opset(AMOVFW, r0)
+ opset(AMOVWD, r0)
+ opset(AMOVDW, r0)
+ opset(ANEGF, r0)
+ opset(ANEGD, r0)
+ opset(AABSD, r0)
+ opset(ATRUNCDW, r0)
+ opset(ATRUNCFW, r0)
+ opset(ATRUNCDV, r0)
+ opset(ATRUNCFV, r0)
+ opset(AMOVVF, r0)
+ opset(AMOVFV, r0)
+ opset(AMOVVD, r0)
+ opset(AMOVDV, r0)
+
+ case AADD:
+ opset(ASGT, r0)
+ opset(ASGTU, r0)
+ opset(AADDU, r0)
opset(AADDV, r0)
- opset(AADDVCC, r0)
- opset(AADDE, r0)
- opset(AADDECC, r0)
- opset(AADDEV, r0)
- opset(AADDEVCC, r0)
- opset(ACRAND, r0)
- opset(ACRANDN, r0)
- opset(ACREQV, r0)
- opset(ACRNAND, r0)
- opset(ACRNOR, r0)
- opset(ACROR, r0)
- opset(ACRORN, r0)
- opset(ACRXOR, r0)
- opset(AMULHD, r0)
- opset(AMULHDCC, r0)
- opset(AMULHDU, r0)
- opset(AMULHDUCC, r0)
- opset(AMULLD, r0)
- opset(AMULLDCC, r0)
- opset(AMULLDVCC, r0)
- opset(AMULLDV, r0)
- opset(ADIVD, r0)
- opset(ADIVDCC, r0)
- opset(ADIVDVCC, r0)
- opset(ADIVDV, r0)
- opset(ADIVDU, r0)
- opset(ADIVDUCC, r0)
- opset(ADIVDUVCC, r0)
- opset(ADIVDUCC, r0)
-
- case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
- opset(AMOVH, r0)
-
- opset(AMOVHZ, r0)
+ opset(AADDVU, r0)
- case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
- opset(AMOVHU, r0)
-
- opset(AMOVHZU, r0)
- opset(AMOVWU, r0)
- opset(AMOVWZU, r0)
- opset(AMOVDU, r0)
- opset(AMOVMW, r0)
-
- case AAND: /* logical op Rb,Rs,Ra; no literal */
- opset(AANDN, r0)
-
- opset(AANDNCC, r0)
- opset(AEQV, r0)
- opset(AEQVCC, r0)
- opset(ANAND, r0)
- opset(ANANDCC, r0)
- opset(ANOR, r0)
- opset(ANORCC, r0)
- opset(AORCC, r0)
- opset(AORN, r0)
- opset(AORNCC, r0)
- opset(AXORCC, r0)
-
- case AADDME: /* op Ra, Rd */
- opset(AADDMECC, r0)
-
- opset(AADDMEV, r0)
- opset(AADDMEVCC, r0)
- opset(AADDZE, r0)
- opset(AADDZECC, r0)
- opset(AADDZEV, r0)
- opset(AADDZEVCC, r0)
- opset(ASUBME, r0)
- opset(ASUBMECC, r0)
- opset(ASUBMEV, r0)
- opset(ASUBMEVCC, r0)
- opset(ASUBZE, r0)
- opset(ASUBZECC, r0)
- opset(ASUBZEV, r0)
- opset(ASUBZEVCC, r0)
-
- case AADDC:
- opset(AADDCCC, r0)
+ case AADDF:
+ opset(ADIVF, r0)
+ opset(ADIVD, r0)
+ opset(AMULF, r0)
+ opset(AMULD, r0)
+ opset(ASUBF, r0)
+ opset(ASUBD, r0)
+ opset(AADDD, r0)
+
+ case AAND:
+ opset(AOR, r0)
+ opset(AXOR, r0)
case ABEQ:
- opset(ABGE, r0)
- opset(ABGT, r0)
- opset(ABLE, r0)
- opset(ABLT, r0)
opset(ABNE, r0)
- opset(ABVC, r0)
- opset(ABVS, r0)
-
- case ABR:
- opset(ABL, r0)
-
- case ABC:
- opset(ABCL, r0)
-
- case AEXTSB: /* op Rs, Ra */
- opset(AEXTSBCC, r0)
-
- opset(AEXTSH, r0)
- opset(AEXTSHCC, r0)
- opset(ACNTLZW, r0)
- opset(ACNTLZWCC, r0)
- opset(ACNTLZD, r0)
- opset(AEXTSW, r0)
- opset(AEXTSWCC, r0)
- opset(ACNTLZDCC, r0)
-
- case AFABS: /* fop [s,]d */
- opset(AFABSCC, r0)
-
- opset(AFNABS, r0)
- opset(AFNABSCC, r0)
- opset(AFNEG, r0)
- opset(AFNEGCC, r0)
- opset(AFRSP, r0)
- opset(AFRSPCC, r0)
- opset(AFCTIW, r0)
- opset(AFCTIWCC, r0)
- opset(AFCTIWZ, r0)
- opset(AFCTIWZCC, r0)
- opset(AFCTID, r0)
- opset(AFCTIDCC, r0)
- opset(AFCTIDZ, r0)
- opset(AFCTIDZCC, r0)
- opset(AFCFID, r0)
- opset(AFCFIDCC, r0)
- opset(AFRES, r0)
- opset(AFRESCC, r0)
- opset(AFRSQRTE, r0)
- opset(AFRSQRTECC, r0)
- opset(AFSQRT, r0)
- opset(AFSQRTCC, r0)
- opset(AFSQRTS, r0)
- opset(AFSQRTSCC, r0)
-
- case AFADD:
- opset(AFADDS, r0)
- opset(AFADDCC, r0)
- opset(AFADDSCC, r0)
- opset(AFDIV, r0)
- opset(AFDIVS, r0)
- opset(AFDIVCC, r0)
- opset(AFDIVSCC, r0)
- opset(AFSUB, r0)
- opset(AFSUBS, r0)
- opset(AFSUBCC, r0)
- opset(AFSUBSCC, r0)
-
- case AFMADD:
- opset(AFMADDCC, r0)
- opset(AFMADDS, r0)
- opset(AFMADDSCC, r0)
- opset(AFMSUB, r0)
- opset(AFMSUBCC, r0)
- opset(AFMSUBS, r0)
- opset(AFMSUBSCC, r0)
- opset(AFNMADD, r0)
- opset(AFNMADDCC, r0)
- opset(AFNMADDS, r0)
- opset(AFNMADDSCC, r0)
- opset(AFNMSUB, r0)
- opset(AFNMSUBCC, r0)
- opset(AFNMSUBS, r0)
- opset(AFNMSUBSCC, r0)
- opset(AFSEL, r0)
- opset(AFSELCC, r0)
-
- case AFMUL:
- opset(AFMULS, r0)
- opset(AFMULCC, r0)
- opset(AFMULSCC, r0)
-
- case AFCMPO:
- opset(AFCMPU, r0)
-
- case AMTFSB0:
- opset(AMTFSB0CC, r0)
- opset(AMTFSB1, r0)
- opset(AMTFSB1CC, r0)
-
- case ANEG: /* op [Ra,] Rd */
- opset(ANEGCC, r0)
-
- opset(ANEGV, r0)
- opset(ANEGVCC, r0)
-
- case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
- opset(AXOR, r0)
- case ASLW:
- opset(ASLWCC, r0)
- opset(ASRW, r0)
- opset(ASRWCC, r0)
+ case ABLEZ:
+ opset(ABGEZ, r0)
+ opset(ABGEZAL, r0)
+ opset(ABLTZ, r0)
+ opset(ABLTZAL, r0)
+ opset(ABGTZ, r0)
- case ASLD:
- opset(ASLDCC, r0)
- opset(ASRD, r0)
- opset(ASRDCC, r0)
+ case AMOVB:
+ opset(AMOVH, r0)
- case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
- opset(ASRAWCC, r0)
+ case AMOVBU:
+ opset(AMOVHU, r0)
- case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
- opset(ASRADCC, r0)
+ case AMUL:
+ opset(AREM, r0)
+ opset(AREMU, r0)
+ opset(ADIVU, r0)
+ opset(AMULU, r0)
+ opset(ADIV, r0)
+ opset(ADIVV, r0)
+ opset(ADIVVU, r0)
+ opset(AMULV, r0)
+ opset(AMULVU, r0)
+ opset(AREMV, r0)
+ opset(AREMVU, r0)
- case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
- opset(ASUB, r0)
+ case ASLL:
+ opset(ASRL, r0)
+ opset(ASRA, r0)
+ opset(ASLLV, r0)
+ opset(ASRAV, r0)
+ opset(ASRLV, r0)
- opset(ASUBCC, r0)
+ case ASUB:
+ opset(ASUBU, r0)
opset(ASUBV, r0)
- opset(ASUBVCC, r0)
- opset(ASUBCCC, r0)
- opset(ASUBCV, r0)
- opset(ASUBCVCC, r0)
- opset(ASUBE, r0)
- opset(ASUBECC, r0)
- opset(ASUBEV, r0)
- opset(ASUBEVCC, r0)
-
- case ASYNC:
- opset(AISYNC, r0)
- opset(APTESYNC, r0)
- opset(ATLBSYNC, r0)
-
- case ARLWMI:
- opset(ARLWMICC, r0)
- opset(ARLWNM, r0)
- opset(ARLWNMCC, r0)
-
- case ARLDMI:
- opset(ARLDMICC, r0)
-
- case ARLDC:
- opset(ARLDCCC, r0)
-
- case ARLDCL:
- opset(ARLDCR, r0)
- opset(ARLDCLCC, r0)
- opset(ARLDCRCC, r0)
-
- case AFMOVD:
- opset(AFMOVDCC, r0)
- opset(AFMOVDU, r0)
- opset(AFMOVS, r0)
- opset(AFMOVSU, r0)
-
- case AECIWX:
- opset(ALWAR, r0)
- opset(ALDAR, r0)
-
- case ASYSCALL: /* just the op; flow of control */
- opset(ARFI, r0)
-
- opset(ARFCI, r0)
- opset(ARFID, r0)
- opset(AHRFID, r0)
-
- case AMOVHBR:
- opset(AMOVWBR, r0)
-
- case ASLBMFEE:
- opset(ASLBMFEV, r0)
-
- case ATW:
- opset(ATD, r0)
-
- case ATLBIE:
- opset(ASLBIE, r0)
- opset(ATLBIEL, r0)
-
- case AEIEIO:
- opset(ASLBIA, r0)
-
- case ACMP:
- opset(ACMPW, r0)
-
- case ACMPU:
- opset(ACMPWU, r0)
-
- case AADD,
- AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
- ALSW,
- AMOVW,
- /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
- AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */
- AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
- AMOVB, /* macro: move byte with sign extension */
- AMOVBU, /* macro: move byte with sign extension & update */
- AMOVFL,
- AMULLW,
- /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
- ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */
- ASTSW,
- ASLBMTE,
+ opset(ASUBVU, r0)
+ opset(ANOR, r0)
+
+ case ASYSCALL:
+ opset(ATLBP, r0)
+ opset(ATLBR, r0)
+ opset(ATLBWI, r0)
+ opset(ATLBWR, r0)
+
+ case ACMPEQF:
+ opset(ACMPGTF, r0)
+ opset(ACMPGTD, r0)
+ opset(ACMPGEF, r0)
+ opset(ACMPGED, r0)
+ opset(ACMPEQD, r0)
+
+ case ABFPT:
+ opset(ABFPF, r0)
+
+ case AMOVWL:
+ opset(AMOVWR, r0)
+ opset(AMOVVR, r0)
+ opset(AMOVVL, r0)
+
+ case AMOVW,
+ AMOVD,
+ AMOVF,
+ AMOVV,
+ ABREAK,
+ ARFE,
+ AJAL,
+ AJMP,
+ AMOVWU,
AWORD,
- ADWORD,
obj.ANOP,
obj.ATEXT,
obj.AUNDEF,
}
}
-func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
- return o<<26 | xo<<1 | oe<<10 | rc&1
+func OP(x uint32, y uint32) uint32 {
+ return x<<3 | y<<0
}
-func OPCC(o uint32, xo uint32, rc uint32) uint32 {
- return OPVCC(o, xo, 0, rc)
+func SP(x uint32, y uint32) uint32 {
+ return x<<29 | y<<26
}
-func OP(o uint32, xo uint32) uint32 {
- return OPVCC(o, xo, 0, 0)
+func BCOND(x uint32, y uint32) uint32 {
+ return x<<19 | y<<16
}
-/* the order is dest, a/s, b/imm for both arithmetic and logical operations */
-func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
- return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
+func MMU(x uint32, y uint32) uint32 {
+ return SP(2, 0) | 16<<21 | x<<3 | y<<0
}
-func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
- return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF
+func FPF(x uint32, y uint32) uint32 {
+ return SP(2, 1) | 16<<21 | x<<3 | y<<0
}
-func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
- return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
+func FPD(x uint32, y uint32) uint32 {
+ return SP(2, 1) | 17<<21 | x<<3 | y<<0
}
-func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {
- return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF
+func FPW(x uint32, y uint32) uint32 {
+ return SP(2, 1) | 20<<21 | x<<3 | y<<0
}
-func OP_BR(op uint32, li uint32, aa uint32) uint32 {
- return op | li&0x03FFFFFC | aa<<1
+func FPV(x uint32, y uint32) uint32 {
+ return SP(2, 1) | 21<<21 | x<<3 | y<<0
}
-func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {
- return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1
+func OP_RRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 {
+ return op | (r1&31)<<16 | (r2&31)<<21 | (r3&31)<<11
}
-func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {
- return op | (bo&0x1F)<<21 | (bi&0x1F)<<16
+func OP_IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
+ return op | i&0xFFFF | (r2&31)<<21 | (r3&31)<<16
}
-func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {
- return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
+func OP_SRR(op uint32, s uint32, r2 uint32, r3 uint32) uint32 {
+ return op | (s&31)<<6 | (r2&31)<<16 | (r3&31)<<11
}
-const (
- /* each rhs is OPVCC(_, _, _, _) */
- OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
- OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0
- OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0
- OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0
- OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0
- OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0
- OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0
- OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0
- OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0
- OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0
- OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0
- OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0
- OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0
- OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0
- OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0
- OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0
- OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0
- OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0
- OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0
- OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0
- OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0
- OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0
- OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0
- OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0
- OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0
- OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0
- OP_OR = 31<<26 | 444<<1 | 0<<10 | 0
- OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0
- OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0
- OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0
- OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0
- OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0
- OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0
- OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0
-)
-
-func oclass(a *obj.Addr) int {
- return int(a.Class) - 1
+func OP_FRRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 {
+ return op | (r1&31)<<16 | (r2&31)<<11 | (r3&31)<<6
}
-// add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2.
-func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) {
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 8
- rel.Sym = s
- rel.Add = int64(uint64(*o1)<<32 | uint64(uint32(*o2)))
- rel.Type = obj.R_ADDRPOWER
+func OP_JMP(op uint32, i uint32) uint32 {
+ return op | i&0x3FFFFFF
}
-/*
- * 32-bit masks
- */
-func getmask(m []byte, v uint32) bool {
- m[1] = 0
- m[0] = m[1]
- if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
- if getmask(m, ^v) {
- i := int(m[0])
- m[0] = m[1] + 1
- m[1] = byte(i - 1)
- return true
- }
-
- return false
- }
-
- for i := 0; i < 32; i++ {
- if v&(1<<uint(31-i)) != 0 {
- m[0] = byte(i)
- for {
- m[1] = byte(i)
- i++
- if i >= 32 || v&(1<<uint(31-i)) == 0 {
- break
- }
- }
-
- for ; i < 32; i++ {
- if v&(1<<uint(31-i)) != 0 {
- return false
- }
- }
- return true
- }
- }
-
- return false
-}
-
-func maskgen(ctxt *obj.Link, p *obj.Prog, m []byte, v uint32) {
- if !getmask(m, v) {
- ctxt.Diag("cannot generate mask #%x\n%v", v, p)
- }
-}
-
-/*
- * 64-bit masks (rldic etc)
- */
-func getmask64(m []byte, v uint64) bool {
- m[1] = 0
- m[0] = m[1]
- for i := 0; i < 64; i++ {
- if v&(uint64(1)<<uint(63-i)) != 0 {
- m[0] = byte(i)
- for {
- m[1] = byte(i)
- i++
- if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 {
- break
- }
- }
-
- for ; i < 64; i++ {
- if v&(uint64(1)<<uint(63-i)) != 0 {
- return false
- }
- }
- return true
- }
- }
-
- return false
-}
-
-func maskgen64(ctxt *obj.Link, p *obj.Prog, m []byte, v uint64) {
- if !getmask64(m, v) {
- ctxt.Diag("cannot generate mask #%x\n%v", v, p)
- }
-}
-
-func loadu32(r int, d int64) uint32 {
- v := int32(d >> 16)
- if isuint32(uint64(d)) {
- return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
- }
- return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))
-}
-
-func high16adjusted(d int32) uint16 {
- if d&0x8000 != 0 {
- return uint16((d >> 16) + 1)
- }
- return uint16(d >> 16)
+func oclass(a *obj.Addr) int {
+ return int(a.Class) - 1
}
func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
o2 := uint32(0)
o3 := uint32(0)
o4 := uint32(0)
- o5 := uint32(0)
- //print("%v => case %d\n", p, o->type);
switch o.type_ {
default:
- ctxt.Diag("unknown type %d", o.type_)
+ ctxt.Diag("unknown type %d %v", o.type_)
prasm(p)
case 0: /* pseudo ops */
break
- case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
- if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
- v := regoff(ctxt, &p.From)
- if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
- //nerrors--;
- ctxt.Diag("literal operation on R0\n%v", p)
- }
-
- o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
- break
- }
-
- o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
+ case 1: /* mov r1,r2 ==> OR r1,r0,r2 */
+ o1 = OP_RRR(oprrr(ctxt, AOR), uint32(p.From.Reg), uint32(REGZERO), uint32(p.To.Reg))
- case 2: /* int/cr/fp op Rb,[Ra],Rd */
+ case 2: /* add/sub r1,[r2],r3 */
r := int(p.Reg)
if r == 0 {
r = int(p.To.Reg)
}
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
+ o1 = OP_RRR(oprrr(ctxt, int(p.As)), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
- case 3: /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
- d := vregoff(ctxt, &p.From)
+ case 3: /* mov $soreg, r ==> or/add $i,o,r */
+ v := regoff(ctxt, &p.From)
- v := int32(d)
r := int(p.From.Reg)
if r == 0 {
r = int(o.param)
}
- if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
- ctxt.Diag("literal operation on R0\n%v", p)
- }
- a := OP_ADDI
- if o.a1 == C_UCON {
- if d&0xffff != 0 {
- log.Fatalf("invalid handling of %v", p)
- }
- v >>= 16
- if r == REGZERO && isuint32(uint64(d)) {
- o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))
- break
- }
-
- a = OP_ADDIS
- } else {
- if int64(int16(d)) != d {
- log.Fatalf("invalid handling of %v", p)
- }
+ a := AADDVU
+ if o.a1 == C_ANDCON {
+ a = AOR
}
- o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
+ o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.To.Reg))
- case 4: /* add/mul $scon,[r1],r2 */
+ case 4: /* add $scon,[r1],r2 */
v := regoff(ctxt, &p.From)
r := int(p.Reg)
if r == 0 {
r = int(p.To.Reg)
}
- if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
- ctxt.Diag("literal operation on R0\n%v", p)
- }
- if int32(int16(v)) != v {
- log.Fatalf("mishandled instruction %v", p)
- }
- o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
+
+ o1 = OP_IRR(opirr(ctxt, int(p.As)), uint32(v), uint32(r), uint32(p.To.Reg))
case 5: /* syscall */
o1 = uint32(oprrr(ctxt, int(p.As)))
- case 6: /* logical op Rb,[Rs,]Ra; no literal */
- r := int(p.Reg)
-
- if r == 0 {
- r = int(p.To.Reg)
+ case 6: /* beq r1,[r2],sbra */
+ v := int32(0)
+ if p.Pcond == nil {
+ v = int32(-4) >> 2
+ } else {
+ v = int32(p.Pcond.Pc-p.Pc-4) >> 2
+ }
+ if (v<<16)>>16 != v {
+ ctxt.Diag("short branch too far\n%v", p)
}
- o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
+ o1 = OP_IRR(opirr(ctxt, int(p.As)), uint32(v), uint32(p.From.Reg), uint32(p.Reg))
+ // for ABFPT and ABFPF only: always fill delay slot with 0
+ // see comments in func preprocess for details.
+ o2 = 0
- case 7: /* mov r, soreg ==> stw o(r) */
+ case 7: /* mov r, soreg ==> sw o(r) */
r := int(p.To.Reg)
-
if r == 0 {
r = int(o.param)
}
v := regoff(ctxt, &p.To)
- if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
- if v != 0 {
- ctxt.Diag("illegal indexed instruction\n%v", p)
- }
- o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
- } else {
- if int32(int16(v)) != v {
- log.Fatalf("mishandled instruction %v", p)
- }
- o1 = AOP_IRR(uint32(opstore(ctxt, int(p.As))), uint32(p.From.Reg), uint32(r), uint32(v))
- }
+ o1 = OP_IRR(opirr(ctxt, int(p.As)), uint32(v), uint32(r), uint32(p.From.Reg))
- case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
+ case 8: /* mov soreg, r ==> lw o(r) */
r := int(p.From.Reg)
-
if r == 0 {
r = int(o.param)
}
v := regoff(ctxt, &p.From)
- if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
- if v != 0 {
- ctxt.Diag("illegal indexed instruction\n%v", p)
- }
- o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
- } else {
- if int32(int16(v)) != v {
- log.Fatalf("mishandled instruction %v", p)
- }
- o1 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
- }
+ o1 = OP_IRR(opirr(ctxt, int(p.As)+ALAST), uint32(v), uint32(r), uint32(p.To.Reg))
- case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
- r := int(p.From.Reg)
+ case 9: /* sll r1,[r2],r3 */
+ r := int(p.Reg)
if r == 0 {
- r = int(o.param)
+ r = int(p.To.Reg)
}
+ o1 = OP_RRR(oprrr(ctxt, int(p.As)), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
+
+ case 10: /* add $con,[r1],r2 ==> mov $con, t; add t,[r1],r2 */
v := regoff(ctxt, &p.From)
- if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
- if v != 0 {
- ctxt.Diag("illegal indexed instruction\n%v", p)
- }
- o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
- } else {
- o1 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
+ a := AOR
+ if v < 0 {
+ a = AADDU
}
- o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
-
- case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
+ o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(0), uint32(REGTMP))
r := int(p.Reg)
-
if r == 0 {
r = int(p.To.Reg)
}
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
+ o2 = OP_RRR(oprrr(ctxt, int(p.As)), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
- case 11: /* br/bl lbra */
+ case 11: /* jmp lbra */
v := int32(0)
-
- if p.Pcond != nil {
- v = int32(p.Pcond.Pc - p.Pc)
- if v&03 != 0 {
- ctxt.Diag("odd branch target address\n%v", p)
- v &^= 03
- }
-
- if v < -(1<<25) || v >= 1<<24 {
- ctxt.Diag("branch too far\n%v", p)
- }
- }
-
- o1 = OP_BR(uint32(opirr(ctxt, int(p.As))), uint32(v), 0)
- if p.To.Sym != nil {
- rel := obj.Addrel(ctxt.Cursym)
- rel.Off = int32(ctxt.Pc)
- rel.Siz = 4
- rel.Sym = p.To.Sym
- v += int32(p.To.Offset)
- if v&03 != 0 {
- ctxt.Diag("odd branch target address\n%v", p)
- v &^= 03
+ if aclass(ctxt, &p.To) == C_SBRA && p.To.Sym == nil && p.As == AJMP {
+ // use PC-relative branch for short branches
+ // BEQ R0, R0, sbra
+ if p.Pcond == nil {
+ v = int32(-4) >> 2
+ } else {
+ v = int32(p.Pcond.Pc-p.Pc-4) >> 2
}
-
- rel.Add = int64(v)
- rel.Type = obj.R_CALLPOWER
- }
-
- case 12: /* movb r,r (extsb); movw r,r (extsw) */
- if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
- v := regoff(ctxt, &p.From)
- if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
- ctxt.Diag("literal operation on R0\n%v", p)
+ if (v<<16)>>16 == v {
+ o1 = OP_IRR(opirr(ctxt, ABEQ), uint32(v), uint32(REGZERO), uint32(REGZERO))
+ break
}
-
- o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
- break
}
-
- if p.As == AMOVW {
- o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
+ if p.Pcond == nil {
+ v = int32(p.Pc) >> 2
} else {
- o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
- }
-
- case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
- if p.As == AMOVBZ {
- o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
- } else if p.As == AMOVH {
- o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
- } else if p.As == AMOVHZ {
- o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
- } else if p.As == AMOVWZ {
- o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
+ v = int32(p.Pcond.Pc) >> 2
+ }
+ o1 = OP_JMP(opirr(ctxt, int(p.As)), uint32(v))
+ if p.To.Sym == nil {
+ p.To.Sym = ctxt.Cursym.Text.From.Sym
+ p.To.Offset = p.Pcond.Pc
+ }
+ rel := obj.Addrel(ctxt.Cursym)
+ rel.Off = int32(ctxt.Pc)
+ rel.Siz = 4
+ rel.Sym = p.To.Sym
+ rel.Add = p.To.Offset
+ if p.As == AJAL {
+ rel.Type = obj.R_CALLMIPS
} else {
- ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
- }
-
- case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
- r := int(p.Reg)
-
- if r == 0 {
- r = int(p.To.Reg)
- }
- d := vregoff(ctxt, p.From3)
- var mask [2]uint8
- maskgen64(ctxt, p, mask[:], uint64(d))
- var a int
- switch p.As {
- case ARLDCL, ARLDCLCC:
- a = int(mask[0]) /* MB */
- if mask[1] != 63 {
- ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
- }
-
- case ARLDCR, ARLDCRCC:
- a = int(mask[1]) /* ME */
- if mask[0] != 0 {
- ctxt.Diag("invalid mask for rotate: %x (start != 0)\n%v", uint64(d), p)
- }
-
- default:
- ctxt.Diag("unexpected op in rldc case\n%v", p)
- a = 0
+ rel.Type = obj.R_JMPMIPS
}
- o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
- o1 |= (uint32(a) & 31) << 6
- if a&0x20 != 0 {
- o1 |= 1 << 5 /* mb[5] is top bit */
+ case 12: /* movbs r,r */
+ v := 16
+ if p.As == AMOVB {
+ v = 24
}
+ o1 = OP_SRR(opirr(ctxt, ASLL), uint32(v), uint32(p.From.Reg), uint32(p.To.Reg))
+ o2 = OP_SRR(opirr(ctxt, ASRA), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
- case 17, /* bc bo,bi,lbra (same for now) */
- 16: /* bc bo,bi,sbra */
- a := 0
-
- if p.From.Type == obj.TYPE_CONST {
- a = int(regoff(ctxt, &p.From))
- }
- r := int(p.Reg)
- if r == 0 {
- r = 0
- }
- v := int32(0)
- if p.Pcond != nil {
- v = int32(p.Pcond.Pc - p.Pc)
- }
- if v&03 != 0 {
- ctxt.Diag("odd branch target address\n%v", p)
- v &^= 03
- }
-
- if v < -(1<<16) || v >= 1<<15 {
- ctxt.Diag("branch too far\n%v", p)
- }
- o1 = OP_BC(uint32(opirr(ctxt, int(p.As))), uint32(a), uint32(r), uint32(v), 0)
-
- case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
- var v int32
- if p.As == ABC || p.As == ABCL {
- v = regoff(ctxt, &p.To) & 31
+ case 13: /* movbu r,r */
+ if p.As == AMOVBU {
+ o1 = OP_IRR(opirr(ctxt, AAND), uint32(0xff), uint32(p.From.Reg), uint32(p.To.Reg))
} else {
- v = 20 /* unconditional */
- }
- o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
- o2 = OPVCC(19, 16, 0, 0)
- if p.As == ABL || p.As == ABCL {
- o2 |= 1
- }
- o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))
-
- case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
- var v int32
- if p.As == ABC || p.As == ABCL {
- v = regoff(ctxt, &p.From) & 31
- } else {
- v = 20 /* unconditional */
- }
- r := int(p.Reg)
- if r == 0 {
- r = 0
- }
- switch oclass(&p.To) {
- case C_CTR:
- o1 = OPVCC(19, 528, 0, 0)
-
- case C_LR:
- o1 = OPVCC(19, 16, 0, 0)
-
- default:
- ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)
- v = 0
- }
-
- if p.As == ABL || p.As == ABCL {
- o1 |= 1
+ o1 = OP_IRR(opirr(ctxt, AAND), uint32(0xffff), uint32(p.From.Reg), uint32(p.To.Reg))
}
- o1 = OP_BCR(o1, uint32(v), uint32(r))
- case 19: /* mov $lcon,r ==> cau+or */
- d := vregoff(ctxt, &p.From)
-
- if p.From.Sym == nil {
- o1 = loadu32(int(p.To.Reg), d)
- o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
+ case 14: /* movwu r,r */
+ o1 = OP_SRR(opirr(ctxt, ASLLV+ALAST), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
+ if p.As == AMOVWU {
+ o2 = OP_SRR(opirr(ctxt, ASRLV+ALAST), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
} else {
- o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(int32(d))))
- o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(d))
- addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
+ o2 = OP_SRR(opirr(ctxt, ASRAV+ALAST), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
}
- //if(dlm) reloc(&p->from, p->pc, 0);
-
- case 20: /* add $ucon,,r */
+ case 16: /* sll $c,[r1],r2 */
v := regoff(ctxt, &p.From)
-
- r := int(p.Reg)
- if r == 0 {
- r = int(p.To.Reg)
- }
- if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
- ctxt.Diag("literal operation on R0\n%v", p)
- }
- o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
-
- case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
- if p.To.Reg == REGTMP || p.Reg == REGTMP {
- ctxt.Diag("cant synthesize large constant\n%v", p)
- }
- d := vregoff(ctxt, &p.From)
- o1 = loadu32(REGTMP, d)
- o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
r := int(p.Reg)
if r == 0 {
r = int(p.To.Reg)
}
- o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r))
- if p.From.Sym != nil {
- ctxt.Diag("%v is not supported", p)
- }
-
- //if(dlm) reloc(&p->from, p->pc, 0);
- case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */
- if p.To.Reg == REGTMP || p.Reg == REGTMP {
- ctxt.Diag("cant synthesize large constant\n%v", p)
- }
- d := vregoff(ctxt, &p.From)
- o1 = loadu32(REGTMP, d)
- o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
- r := int(p.Reg)
- if r == 0 {
- r = int(p.To.Reg)
- }
- o3 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r))
- if p.From.Sym != nil {
- ctxt.Diag("%v is not supported", p)
+ /* OP_SRR will use only the low 5 bits of the shift value */
+ if v >= 32 && vshift(p.As) {
+ o1 = OP_SRR(opirr(ctxt, int(p.As)+ALAST), uint32(v-32), uint32(r), uint32(p.To.Reg))
+ } else {
+ o1 = OP_SRR(opirr(ctxt, int(p.As)), uint32(v), uint32(r), uint32(p.To.Reg))
}
- //if(dlm) reloc(&p->from, p->pc, 0);
-
- /*24*/
- case 25:
- /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
- v := regoff(ctxt, &p.From)
-
- if v < 0 {
- v = 0
- } else if v > 63 {
- v = 63
- }
+ case 18: /* jmp [r1],0(r2) */
r := int(p.Reg)
- if r == 0 {
- r = int(p.To.Reg)
- }
- var a int
- switch p.As {
- case ASLD, ASLDCC:
- a = int(63 - v)
- o1 = OP_RLDICR
-
- case ASRD, ASRDCC:
- a = int(v)
- v = 64 - v
- o1 = OP_RLDICL
-
- default:
- ctxt.Diag("unexpected op in sldi case\n%v", p)
- a = 0
- o1 = 0
- }
-
- o1 = AOP_RRR(o1, uint32(r), uint32(p.To.Reg), (uint32(v) & 0x1F))
- o1 |= (uint32(a) & 31) << 6
- if v&0x20 != 0 {
- o1 |= 1 << 1
- }
- if a&0x20 != 0 {
- o1 |= 1 << 5 /* mb[5] is top bit */
- }
- if p.As == ASLDCC || p.As == ASRDCC {
- o1 |= 1 /* Rc */
- }
-
- case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
- if p.To.Reg == REGTMP {
- ctxt.Diag("can't synthesize large constant\n%v", p)
- }
- v := regoff(ctxt, &p.From)
- r := int(p.From.Reg)
if r == 0 {
r = int(o.param)
}
- o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
- o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
-
- case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
- v := regoff(ctxt, p.From3)
-
- r := int(p.From.Reg)
- o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
+ o1 = OP_RRR(oprrr(ctxt, int(p.As)), uint32(0), uint32(p.To.Reg), uint32(r))
+ rel := obj.Addrel(ctxt.Cursym)
+ rel.Off = int32(ctxt.Pc)
+ rel.Siz = 0
+ rel.Type = obj.R_CALLIND
- case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
- if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
- ctxt.Diag("can't synthesize large constant\n%v", p)
- }
- v := regoff(ctxt, p.From3)
- o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
- o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
- o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
- if p.From.Sym != nil {
- ctxt.Diag("%v is not supported", p)
- }
-
- //if(dlm) reloc(&p->from3, p->pc, 0);
-
- case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
+ case 19: /* mov $lcon,r ==> lu+or */
v := regoff(ctxt, &p.From)
-
- d := vregoff(ctxt, p.From3)
- var mask [2]uint8
- maskgen64(ctxt, p, mask[:], uint64(d))
- var a int
- switch p.As {
- case ARLDC, ARLDCCC:
- a = int(mask[0]) /* MB */
- if int32(mask[1]) != (63 - v) {
- ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
- }
-
- case ARLDCL, ARLDCLCC:
- a = int(mask[0]) /* MB */
- if mask[1] != 63 {
- ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
- }
-
- case ARLDCR, ARLDCRCC:
- a = int(mask[1]) /* ME */
- if mask[0] != 0 {
- ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
- }
-
- default:
- ctxt.Diag("unexpected op in rldic case\n%v", p)
- a = 0
- }
-
- o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
- o1 |= (uint32(a) & 31) << 6
- if v&0x20 != 0 {
- o1 |= 1 << 1
- }
- if a&0x20 != 0 {
- o1 |= 1 << 5 /* mb[5] is top bit */
- }
-
- case 30: /* rldimi $sh,s,$mask,a */
- v := regoff(ctxt, &p.From)
-
- d := vregoff(ctxt, p.From3)
- var mask [2]uint8
- maskgen64(ctxt, p, mask[:], uint64(d))
- if int32(mask[1]) != (63 - v) {
- ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
- }
- o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
- o1 |= (uint32(mask[0]) & 31) << 6
- if v&0x20 != 0 {
- o1 |= 1 << 1
- }
- if mask[0]&0x20 != 0 {
- o1 |= 1 << 5 /* mb[5] is top bit */
- }
-
- case 31: /* dword */
- d := vregoff(ctxt, &p.From)
-
- if ctxt.Arch.ByteOrder == binary.BigEndian {
- o1 = uint32(d >> 32)
- o2 = uint32(d)
- } else {
- o1 = uint32(d)
- o2 = uint32(d >> 32)
- }
-
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg))
+ o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
if p.From.Sym != nil {
rel := obj.Addrel(ctxt.Cursym)
rel.Off = int32(ctxt.Pc)
rel.Siz = 8
rel.Sym = p.From.Sym
rel.Add = p.From.Offset
- rel.Type = obj.R_ADDR
- o2 = 0
- o1 = o2
+ rel.Type = obj.R_ADDRMIPS
}
- case 32: /* fmul frc,fra,frd */
- r := int(p.Reg)
-
- if r == 0 {
- r = int(p.To.Reg)
+ case 20: /* mov lo/hi,r */
+ a := OP(2, 0) /* mfhi */
+ if p.From.Reg == REG_LO {
+ a = OP(2, 2) /* mflo */
}
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
+ o1 = OP_RRR(a, uint32(REGZERO), uint32(REGZERO), uint32(p.To.Reg))
- case 33: /* fabs [frb,]frd; fmr. frb,frd */
- r := int(p.From.Reg)
-
- if oclass(&p.From) == C_NONE {
- r = int(p.To.Reg)
+ case 21: /* mov r,lo/hi */
+ a := OP(2, 1) /* mthi */
+ if p.To.Reg == REG_LO {
+ a = OP(2, 3) /* mtlo */
}
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), 0, uint32(r))
+ o1 = OP_RRR(a, uint32(REGZERO), uint32(p.From.Reg), uint32(REGZERO))
- case 34: /* FMADDx fra,frb,frc,frd (d=a*b+c); FSELx a<0? (d=b): (d=c) */
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.From3.Reg)&31)<<6
+ case 22: /* mul r1,r2 */
+ o1 = OP_RRR(oprrr(ctxt, int(p.As)), uint32(p.From.Reg), uint32(p.Reg), uint32(REGZERO))
- case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
- v := regoff(ctxt, &p.To)
-
- r := int(p.To.Reg)
+ case 23: /* add $lcon,r1,r2 ==> lu+or+add */
+ v := regoff(ctxt, &p.From)
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
+ o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
+ r := int(p.Reg)
if r == 0 {
- r = int(o.param)
+ r = int(p.To.Reg)
}
- o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
- o2 = AOP_IRR(uint32(opstore(ctxt, int(p.As))), uint32(p.From.Reg), REGTMP, uint32(v))
+ o3 = OP_RRR(oprrr(ctxt, int(p.As)), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
- case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
+ case 24: /* mov $ucon,r ==> lu r */
v := regoff(ctxt, &p.From)
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(v>>16), uint32(REGZERO), uint32(p.To.Reg))
- r := int(p.From.Reg)
+ case 25: /* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */
+ v := regoff(ctxt, &p.From)
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
+ r := int(p.Reg)
if r == 0 {
- r = int(o.param)
+ r = int(p.To.Reg)
}
- o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
- o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
+ o2 = OP_RRR(oprrr(ctxt, int(p.As)), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
- case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
+ case 26: /* mov $lsext/auto/oreg,r ==> lu+or+add */
v := regoff(ctxt, &p.From)
-
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
+ o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
r := int(p.From.Reg)
if r == 0 {
r = int(o.param)
}
- o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
- o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
- o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
+ o3 = OP_RRR(oprrr(ctxt, AADDVU), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
- case 40: /* word */
- o1 = uint32(regoff(ctxt, &p.From))
-
- case 41: /* stswi */
- o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11
-
- case 42: /* lswi */
- o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11
-
- case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, uint32(p.From.Index), uint32(p.From.Reg))
-
- case 44: /* indexed store */
- o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
-
- case 45: /* indexed load */
- o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
-
- case 46: /* plain op */
- o1 = uint32(oprrr(ctxt, int(p.As)))
-
- case 47: /* op Ra, Rd; also op [Ra,] Rd */
+ case 27: /* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */
+ v := regoff(ctxt, &p.From)
r := int(p.From.Reg)
-
if r == 0 {
- r = int(p.To.Reg)
+ r = int(o.param)
}
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
-
- case 48: /* op Rs, Ra */
- r := int(p.From.Reg)
-
- if r == 0 {
- r = int(p.To.Reg)
+ a := AMOVF + ALAST
+ if p.As == AMOVD {
+ a = AMOVD + ALAST
}
- o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0)
+ switch o.size {
+ case 16:
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
+ o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
+ o3 = OP_RRR(opirr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
+ o4 = OP_IRR(opirr(ctxt, a), uint32(0), uint32(r), uint32(p.To.Reg))
- case 49: /* op Rb; op $n, Rb */
- if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
- v := regoff(ctxt, &p.From) & 1
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
- } else {
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.From.Reg))
+ case 4:
+ o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.To.Reg))
}
- case 50: /* rem[u] r1[,r2],r3 */
- r := int(p.Reg)
-
+ case 28: /* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */
+ v := regoff(ctxt, &p.To)
+ r := int(p.To.Reg)
if r == 0 {
- r = int(p.To.Reg)
- }
- v := oprrr(ctxt, int(p.As))
- t := v & (1<<10 | 1) /* OE|Rc */
- o1 = AOP_RRR(uint32(v)&^uint32(t), REGTMP, uint32(r), uint32(p.From.Reg))
- o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
- o3 = AOP_RRR(OP_SUBF|uint32(t), uint32(p.To.Reg), REGTMP, uint32(r))
- if p.As == AREMU {
- o4 = o3
-
- /* Clear top 32 bits */
- o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5
+ r = int(o.param)
}
-
- case 51: /* remd[u] r1[,r2],r3 */
- r := int(p.Reg)
-
- if r == 0 {
- r = int(p.To.Reg)
+ a := AMOVF
+ if p.As == AMOVD {
+ a = AMOVD
}
- v := oprrr(ctxt, int(p.As))
- t := v & (1<<10 | 1) /* OE|Rc */
- o1 = AOP_RRR(uint32(v)&^uint32(t), REGTMP, uint32(r), uint32(p.From.Reg))
- o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
- o3 = AOP_RRR(OP_SUBF|uint32(t), uint32(p.To.Reg), REGTMP, uint32(r))
-
- case 52: /* mtfsbNx cr(n) */
- v := regoff(ctxt, &p.From) & 31
-
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(v), 0, 0)
-
- case 53: /* mffsX ,fr1 */
- o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
+ switch o.size {
+ case 16:
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
+ o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
+ o3 = OP_RRR(opirr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
+ o4 = OP_IRR(opirr(ctxt, a), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
- case 54: /* mov msr,r1; mov r1, msr*/
- if oclass(&p.From) == C_REG {
- if p.As == AMOVD {
- o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
- } else {
- o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
- }
- } else {
- o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
+ case 4:
+ o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(r), uint32(p.From.Reg))
}
- case 55: /* op Rb, Rd */
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), 0, uint32(p.From.Reg))
-
- case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
- v := regoff(ctxt, &p.From)
-
- r := int(p.Reg)
- if r == 0 {
- r = int(p.To.Reg)
- }
- o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.To.Reg), uint32(v)&31)
- if p.As == ASRAD && (v&0x20 != 0) {
- o1 |= 1 << 1 /* mb[5] */
- }
+ case 30: /* movw r,fr */
+ a := SP(2, 1) | (4 << 21) /* mtc1 */
+ o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg))
- case 57: /* slw $sh,[s,]a -> rlwinm ... */
- v := regoff(ctxt, &p.From)
+ case 31: /* movw fr,r */
+ a := SP(2, 1) | (0 << 21) /* mtc1 */
+ o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
+ case 32: /* fadd fr1,[fr2],fr3 */
r := int(p.Reg)
if r == 0 {
r = int(p.To.Reg)
}
+ o1 = OP_FRRR(oprrr(ctxt, int(p.As)), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
- /*
- * Let user (gs) shoot himself in the foot.
- * qc has already complained.
- *
- if(v < 0 || v > 31)
- ctxt->diag("illegal shift %ld\n%v", v, p);
- */
- if v < 0 {
- v = 0
- } else if v > 32 {
- v = 32
- }
- var mask [2]uint8
- if p.As == ASRW || p.As == ASRWCC { /* shift right */
- mask[0] = uint8(v)
- mask[1] = 31
- v = 32 - v
- } else {
- mask[0] = 0
- mask[1] = uint8(31 - v)
- }
-
- o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))
- if p.As == ASLWCC || p.As == ASRWCC {
- o1 |= 1 /* Rc */
- }
+ case 33: /* fabs fr1, fr3 */
+ o1 = OP_FRRR(oprrr(ctxt, int(p.As)), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
- case 58: /* logical $andcon,[s],a */
+ case 34: /* mov $con,fr ==> or/add $i,t; mov t,fr */
v := regoff(ctxt, &p.From)
-
- r := int(p.Reg)
- if r == 0 {
- r = int(p.To.Reg)
+ a := AADDU
+ if o.a1 == C_ANDCON {
+ a = AOR
}
- o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v))
+ o1 = OP_IRR(opirr(ctxt, a), uint32(v), uint32(0), uint32(REGTMP))
+ o2 = OP_RRR(SP(2, 1)|(4<<21), uint32(REGTMP), uint32(0), uint32(p.To.Reg)) /* mtc1 */
- case 59: /* or/and $ucon,,r */
- v := regoff(ctxt, &p.From)
-
- r := int(p.Reg)
+ case 35: /* mov r,lext/auto/oreg ==> sw o(r) */
+ v := regoff(ctxt, &p.To)
+ r := int(p.To.Reg)
if r == 0 {
- r = int(p.To.Reg)
+ r = int(o.param)
}
- o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */
-
- case 60: /* tw to,a,b */
- r := int(regoff(ctxt, &p.From) & 31)
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
+ o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
+ o3 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
+ o4 = OP_IRR(opirr(ctxt, int(p.As)), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
-
- case 61: /* tw to,a,$simm */
- r := int(regoff(ctxt, &p.From) & 31)
-
- v := regoff(ctxt, &p.To)
- o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.Reg), uint32(v))
-
- case 62: /* rlwmi $sh,s,$mask,a */
+ case 36: /* mov lext/auto/oreg,r ==> lw o(r30) */
v := regoff(ctxt, &p.From)
-
- var mask [2]uint8
- maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3)))
- o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
- o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
-
- case 63: /* rlwmi b,s,$mask,a */
- var mask [2]uint8
- maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3)))
-
- o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
- o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
-
- case 64: /* mtfsf fr[, $m] {,fpcsr} */
- var v int32
- if p.From3Type() != obj.TYPE_NONE {
- v = regoff(ctxt, p.From3) & 255
- } else {
- v = 255
- }
- o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
-
- case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
- if p.To.Reg == 0 {
- ctxt.Diag("must specify FPSCR(n)\n%v", p)
- }
- o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12
-
- case 66: /* mov spr,r1; mov r1,spr, also dcr */
- var r int
- var v int32
- if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
- r = int(p.From.Reg)
- v = int32(p.To.Reg)
- if REG_DCR0 <= v && v <= REG_DCR0+1023 {
- o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
- } else {
- o1 = OPVCC(31, 467, 0, 0) /* mtspr */
- }
- } else {
- r = int(p.To.Reg)
- v = int32(p.From.Reg)
- if REG_DCR0 <= v && v <= REG_DCR0+1023 {
- o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
- } else {
- o1 = OPVCC(31, 339, 0, 0) /* mfspr */
- }
- }
-
- o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
-
- case 67: /* mcrf crfD,crfS */
- if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_CR0 || REG_CR7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg {
- ctxt.Diag("illegal CR field number\n%v", p)
- }
- o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
-
- case 68: /* mfcr rD; mfocrf CRM,rD */
- if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
- v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */
- o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
- } else {
- o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
- }
-
- case 69: /* mtcrf CRM,rS */
- var v int32
- if p.From3Type() != obj.TYPE_NONE {
- if p.To.Reg != 0 {
- ctxt.Diag("can't use both mask and CR(n)\n%v", p)
- }
- v = regoff(ctxt, p.From3) & 0xff
- } else {
- if p.To.Reg == 0 {
- v = 0xff /* CR */
- } else {
- v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
- }
- }
-
- o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
-
- case 70: /* [f]cmp r,r,cr*/
- var r int
- if p.Reg == 0 {
- r = 0
- } else {
- r = (int(p.Reg) & 7) << 2
- }
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
-
- case 71: /* cmp[l] r,i,cr*/
- var r int
- if p.Reg == 0 {
- r = 0
- } else {
- r = (int(p.Reg) & 7) << 2
+ r := int(p.From.Reg)
+ if r == 0 {
+ r = int(o.param)
}
- o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff
-
- case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
- o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.From.Reg), 0, uint32(p.To.Reg))
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(v>>16), uint32(REGZERO), uint32(REGTMP))
+ o2 = OP_IRR(opirr(ctxt, AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
+ o3 = OP_RRR(oprrr(ctxt, AADDVU), uint32(r), uint32(REGTMP), uint32(REGTMP))
+ o4 = OP_IRR(opirr(ctxt, int(p.As)+ALAST), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
- case 73: /* mcrfs crfD,crfS */
- if p.From.Type != obj.TYPE_REG || p.From.Reg != REG_FPSCR || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg {
- ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
+ case 37: /* movw r,mr */
+ a := SP(2, 0) | (4 << 21) /* mtc0 */
+ if p.As == AMOVV {
+ a = SP(2, 0) | (5 << 21) /* dmtc0 */
}
- o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
+ o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg))
- case 77: /* syscall $scon, syscall Rx */
- if p.From.Type == obj.TYPE_CONST {
- if p.From.Offset > BIG || p.From.Offset < -BIG {
- ctxt.Diag("illegal syscall, sysnum too large: %v", p)
- }
- o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
- } else if p.From.Type == obj.TYPE_REG {
- o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
- } else {
- ctxt.Diag("illegal syscall: %v", p)
- o1 = 0x7fe00008 // trap always
+ case 38: /* movw mr,r */
+ a := SP(2, 0) | (0 << 21) /* mfc0 */
+ if p.As == AMOVV {
+ a = SP(2, 0) | (1 << 21) /* dmfc0 */
}
+ o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
- o2 = uint32(oprrr(ctxt, int(p.As)))
- o3 = AOP_RRR(uint32(oprrr(ctxt, AXOR)), REGZERO, REGZERO, REGZERO) // XOR R0, R0
-
- case 78: /* undef */
- o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed
- always to be an illegal instruction." */
-
- /* relocation operations */
- case 74:
- v := regoff(ctxt, &p.To)
-
- o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(v)))
- o2 = AOP_IRR(uint32(opstore(ctxt, int(p.As))), uint32(p.From.Reg), REGTMP, uint32(v))
- addaddrreloc(ctxt, p.To.Sym, &o1, &o2)
-
- //if(dlm) reloc(&p->to, p->pc, 1);
-
- case 75:
- v := regoff(ctxt, &p.From)
- o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(v)))
- o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
- addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
-
- //if(dlm) reloc(&p->from, p->pc, 1);
-
- case 76:
- v := regoff(ctxt, &p.From)
- o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(v)))
- o2 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(v))
- addaddrreloc(ctxt, p.From.Sym, &o1, &o2)
- o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
-
- //if(dlm) reloc(&p->from, p->pc, 1);
+ case 40: /* word */
+ o1 = uint32(regoff(ctxt, &p.From))
+ case 41: /* movw f,fcr */
+ o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(REGZERO), uint32(0), uint32(p.To.Reg)) /* mfcc1 */
+ o2 = OP_RRR(SP(2, 1)|(6<<21), uint32(p.From.Reg), uint32(0), uint32(p.To.Reg)) /* mtcc1 */
+
+ case 42: /* movw fcr,r */
+ o1 = OP_RRR(SP(2, 1)|(2<<21), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg)) /* mfcc1 */
+
+ case 47: /* movv r,fr */
+ a := SP(2, 1) | (5 << 21) /* dmtc1 */
+ o1 = OP_RRR(a, uint32(p.From.Reg), uint32(0), uint32(p.To.Reg))
+
+ case 48: /* movv fr,r */
+ a := SP(2, 1) | (1 << 21) /* dmtc1 */
+ o1 = OP_RRR(a, uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
+
+ case 49: /* undef */
+ o1 = 8 /* JMP (R0) */
+
+ /* relocation operations */
+ case 50: /* mov r,addr ==> lu + or + sw (REGTMP) */
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(0), uint32(REGZERO), uint32(REGTMP))
+ o2 = OP_IRR(opirr(ctxt, AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
+ rel := obj.Addrel(ctxt.Cursym)
+ rel.Off = int32(ctxt.Pc)
+ rel.Siz = 8
+ rel.Sym = p.To.Sym
+ rel.Add = p.To.Offset
+ rel.Type = obj.R_ADDRMIPS
+ o3 = OP_IRR(opirr(ctxt, int(p.As)), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
+
+ case 51: /* mov addr,r ==> lu + or + lw (REGTMP) */
+ o1 = OP_IRR(opirr(ctxt, ALAST), uint32(0), uint32(REGZERO), uint32(REGTMP))
+ o2 = OP_IRR(opirr(ctxt, AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
+ rel := obj.Addrel(ctxt.Cursym)
+ rel.Off = int32(ctxt.Pc)
+ rel.Siz = 8
+ rel.Sym = p.From.Sym
+ rel.Add = p.From.Offset
+ rel.Type = obj.R_ADDRMIPS
+ o3 = OP_IRR(opirr(ctxt, int(p.As)+ALAST), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
}
out[0] = o1
out[1] = o2
out[2] = o3
out[3] = o4
- out[4] = o5
return
}
func vregoff(ctxt *obj.Link, a *obj.Addr) int64 {
ctxt.Instoffset = 0
- if a != nil {
- aclass(ctxt, a)
- }
+ aclass(ctxt, a)
return ctxt.Instoffset
}
return int32(vregoff(ctxt, a))
}
-func oprrr(ctxt *obj.Link, a int) int32 {
+func oprrr(ctxt *obj.Link, a int) uint32 {
switch a {
case AADD:
- return int32(OPVCC(31, 266, 0, 0))
- case AADDCC:
- return int32(OPVCC(31, 266, 0, 1))
- case AADDV:
- return int32(OPVCC(31, 266, 1, 0))
- case AADDVCC:
- return int32(OPVCC(31, 266, 1, 1))
- case AADDC:
- return int32(OPVCC(31, 10, 0, 0))
- case AADDCCC:
- return int32(OPVCC(31, 10, 0, 1))
- case AADDCV:
- return int32(OPVCC(31, 10, 1, 0))
- case AADDCVCC:
- return int32(OPVCC(31, 10, 1, 1))
- case AADDE:
- return int32(OPVCC(31, 138, 0, 0))
- case AADDECC:
- return int32(OPVCC(31, 138, 0, 1))
- case AADDEV:
- return int32(OPVCC(31, 138, 1, 0))
- case AADDEVCC:
- return int32(OPVCC(31, 138, 1, 1))
- case AADDME:
- return int32(OPVCC(31, 234, 0, 0))
- case AADDMECC:
- return int32(OPVCC(31, 234, 0, 1))
- case AADDMEV:
- return int32(OPVCC(31, 234, 1, 0))
- case AADDMEVCC:
- return int32(OPVCC(31, 234, 1, 1))
- case AADDZE:
- return int32(OPVCC(31, 202, 0, 0))
- case AADDZECC:
- return int32(OPVCC(31, 202, 0, 1))
- case AADDZEV:
- return int32(OPVCC(31, 202, 1, 0))
- case AADDZEVCC:
- return int32(OPVCC(31, 202, 1, 1))
-
+ return OP(4, 0)
+ case AADDU:
+ return OP(4, 1)
+ case ASGT:
+ return OP(5, 2)
+ case ASGTU:
+ return OP(5, 3)
case AAND:
- return int32(OPVCC(31, 28, 0, 0))
- case AANDCC:
- return int32(OPVCC(31, 28, 0, 1))
- case AANDN:
- return int32(OPVCC(31, 60, 0, 0))
- case AANDNCC:
- return int32(OPVCC(31, 60, 0, 1))
-
- case ACMP:
- return int32(OPVCC(31, 0, 0, 0) | 1<<21) /* L=1 */
- case ACMPU:
- return int32(OPVCC(31, 32, 0, 0) | 1<<21)
- case ACMPW:
- return int32(OPVCC(31, 0, 0, 0)) /* L=0 */
- case ACMPWU:
- return int32(OPVCC(31, 32, 0, 0))
-
- case ACNTLZW:
- return int32(OPVCC(31, 26, 0, 0))
- case ACNTLZWCC:
- return int32(OPVCC(31, 26, 0, 1))
- case ACNTLZD:
- return int32(OPVCC(31, 58, 0, 0))
- case ACNTLZDCC:
- return int32(OPVCC(31, 58, 0, 1))
-
- case ACRAND:
- return int32(OPVCC(19, 257, 0, 0))
- case ACRANDN:
- return int32(OPVCC(19, 129, 0, 0))
- case ACREQV:
- return int32(OPVCC(19, 289, 0, 0))
- case ACRNAND:
- return int32(OPVCC(19, 225, 0, 0))
- case ACRNOR:
- return int32(OPVCC(19, 33, 0, 0))
- case ACROR:
- return int32(OPVCC(19, 449, 0, 0))
- case ACRORN:
- return int32(OPVCC(19, 417, 0, 0))
- case ACRXOR:
- return int32(OPVCC(19, 193, 0, 0))
-
- case ADCBF:
- return int32(OPVCC(31, 86, 0, 0))
- case ADCBI:
- return int32(OPVCC(31, 470, 0, 0))
- case ADCBST:
- return int32(OPVCC(31, 54, 0, 0))
- case ADCBT:
- return int32(OPVCC(31, 278, 0, 0))
- case ADCBTST:
- return int32(OPVCC(31, 246, 0, 0))
- case ADCBZ:
- return int32(OPVCC(31, 1014, 0, 0))
-
- case AREM, ADIVW:
- return int32(OPVCC(31, 491, 0, 0))
-
- case AREMCC, ADIVWCC:
- return int32(OPVCC(31, 491, 0, 1))
-
- case AREMV, ADIVWV:
- return int32(OPVCC(31, 491, 1, 0))
-
- case AREMVCC, ADIVWVCC:
- return int32(OPVCC(31, 491, 1, 1))
-
- case AREMU, ADIVWU:
- return int32(OPVCC(31, 459, 0, 0))
-
- case AREMUCC, ADIVWUCC:
- return int32(OPVCC(31, 459, 0, 1))
-
- case AREMUV, ADIVWUV:
- return int32(OPVCC(31, 459, 1, 0))
-
- case AREMUVCC, ADIVWUVCC:
- return int32(OPVCC(31, 459, 1, 1))
-
- case AREMD, ADIVD:
- return int32(OPVCC(31, 489, 0, 0))
-
- case AREMDCC, ADIVDCC:
- return int32(OPVCC(31, 489, 0, 1))
-
- case AREMDV, ADIVDV:
- return int32(OPVCC(31, 489, 1, 0))
-
- case AREMDVCC, ADIVDVCC:
- return int32(OPVCC(31, 489, 1, 1))
-
- case AREMDU, ADIVDU:
- return int32(OPVCC(31, 457, 0, 0))
-
- case AREMDUCC, ADIVDUCC:
- return int32(OPVCC(31, 457, 0, 1))
-
- case AREMDUV, ADIVDUV:
- return int32(OPVCC(31, 457, 1, 0))
-
- case AREMDUVCC, ADIVDUVCC:
- return int32(OPVCC(31, 457, 1, 1))
-
- case AEIEIO:
- return int32(OPVCC(31, 854, 0, 0))
-
- case AEQV:
- return int32(OPVCC(31, 284, 0, 0))
- case AEQVCC:
- return int32(OPVCC(31, 284, 0, 1))
-
- case AEXTSB:
- return int32(OPVCC(31, 954, 0, 0))
- case AEXTSBCC:
- return int32(OPVCC(31, 954, 0, 1))
- case AEXTSH:
- return int32(OPVCC(31, 922, 0, 0))
- case AEXTSHCC:
- return int32(OPVCC(31, 922, 0, 1))
- case AEXTSW:
- return int32(OPVCC(31, 986, 0, 0))
- case AEXTSWCC:
- return int32(OPVCC(31, 986, 0, 1))
-
- case AFABS:
- return int32(OPVCC(63, 264, 0, 0))
- case AFABSCC:
- return int32(OPVCC(63, 264, 0, 1))
- case AFADD:
- return int32(OPVCC(63, 21, 0, 0))
- case AFADDCC:
- return int32(OPVCC(63, 21, 0, 1))
- case AFADDS:
- return int32(OPVCC(59, 21, 0, 0))
- case AFADDSCC:
- return int32(OPVCC(59, 21, 0, 1))
- case AFCMPO:
- return int32(OPVCC(63, 32, 0, 0))
- case AFCMPU:
- return int32(OPVCC(63, 0, 0, 0))
- case AFCFID:
- return int32(OPVCC(63, 846, 0, 0))
- case AFCFIDCC:
- return int32(OPVCC(63, 846, 0, 1))
- case AFCTIW:
- return int32(OPVCC(63, 14, 0, 0))
- case AFCTIWCC:
- return int32(OPVCC(63, 14, 0, 1))
- case AFCTIWZ:
- return int32(OPVCC(63, 15, 0, 0))
- case AFCTIWZCC:
- return int32(OPVCC(63, 15, 0, 1))
- case AFCTID:
- return int32(OPVCC(63, 814, 0, 0))
- case AFCTIDCC:
- return int32(OPVCC(63, 814, 0, 1))
- case AFCTIDZ:
- return int32(OPVCC(63, 815, 0, 0))
- case AFCTIDZCC:
- return int32(OPVCC(63, 815, 0, 1))
- case AFDIV:
- return int32(OPVCC(63, 18, 0, 0))
- case AFDIVCC:
- return int32(OPVCC(63, 18, 0, 1))
- case AFDIVS:
- return int32(OPVCC(59, 18, 0, 0))
- case AFDIVSCC:
- return int32(OPVCC(59, 18, 0, 1))
- case AFMADD:
- return int32(OPVCC(63, 29, 0, 0))
- case AFMADDCC:
- return int32(OPVCC(63, 29, 0, 1))
- case AFMADDS:
- return int32(OPVCC(59, 29, 0, 0))
- case AFMADDSCC:
- return int32(OPVCC(59, 29, 0, 1))
-
- case AFMOVS, AFMOVD:
- return int32(OPVCC(63, 72, 0, 0)) /* load */
- case AFMOVDCC:
- return int32(OPVCC(63, 72, 0, 1))
- case AFMSUB:
- return int32(OPVCC(63, 28, 0, 0))
- case AFMSUBCC:
- return int32(OPVCC(63, 28, 0, 1))
- case AFMSUBS:
- return int32(OPVCC(59, 28, 0, 0))
- case AFMSUBSCC:
- return int32(OPVCC(59, 28, 0, 1))
- case AFMUL:
- return int32(OPVCC(63, 25, 0, 0))
- case AFMULCC:
- return int32(OPVCC(63, 25, 0, 1))
- case AFMULS:
- return int32(OPVCC(59, 25, 0, 0))
- case AFMULSCC:
- return int32(OPVCC(59, 25, 0, 1))
- case AFNABS:
- return int32(OPVCC(63, 136, 0, 0))
- case AFNABSCC:
- return int32(OPVCC(63, 136, 0, 1))
- case AFNEG:
- return int32(OPVCC(63, 40, 0, 0))
- case AFNEGCC:
- return int32(OPVCC(63, 40, 0, 1))
- case AFNMADD:
- return int32(OPVCC(63, 31, 0, 0))
- case AFNMADDCC:
- return int32(OPVCC(63, 31, 0, 1))
- case AFNMADDS:
- return int32(OPVCC(59, 31, 0, 0))
- case AFNMADDSCC:
- return int32(OPVCC(59, 31, 0, 1))
- case AFNMSUB:
- return int32(OPVCC(63, 30, 0, 0))
- case AFNMSUBCC:
- return int32(OPVCC(63, 30, 0, 1))
- case AFNMSUBS:
- return int32(OPVCC(59, 30, 0, 0))
- case AFNMSUBSCC:
- return int32(OPVCC(59, 30, 0, 1))
- case AFRES:
- return int32(OPVCC(59, 24, 0, 0))
- case AFRESCC:
- return int32(OPVCC(59, 24, 0, 1))
- case AFRSP:
- return int32(OPVCC(63, 12, 0, 0))
- case AFRSPCC:
- return int32(OPVCC(63, 12, 0, 1))
- case AFRSQRTE:
- return int32(OPVCC(63, 26, 0, 0))
- case AFRSQRTECC:
- return int32(OPVCC(63, 26, 0, 1))
- case AFSEL:
- return int32(OPVCC(63, 23, 0, 0))
- case AFSELCC:
- return int32(OPVCC(63, 23, 0, 1))
- case AFSQRT:
- return int32(OPVCC(63, 22, 0, 0))
- case AFSQRTCC:
- return int32(OPVCC(63, 22, 0, 1))
- case AFSQRTS:
- return int32(OPVCC(59, 22, 0, 0))
- case AFSQRTSCC:
- return int32(OPVCC(59, 22, 0, 1))
- case AFSUB:
- return int32(OPVCC(63, 20, 0, 0))
- case AFSUBCC:
- return int32(OPVCC(63, 20, 0, 1))
- case AFSUBS:
- return int32(OPVCC(59, 20, 0, 0))
- case AFSUBSCC:
- return int32(OPVCC(59, 20, 0, 1))
-
- case AICBI:
- return int32(OPVCC(31, 982, 0, 0))
- case AISYNC:
- return int32(OPVCC(19, 150, 0, 0))
-
- case AMTFSB0:
- return int32(OPVCC(63, 70, 0, 0))
- case AMTFSB0CC:
- return int32(OPVCC(63, 70, 0, 1))
- case AMTFSB1:
- return int32(OPVCC(63, 38, 0, 0))
- case AMTFSB1CC:
- return int32(OPVCC(63, 38, 0, 1))
-
- case AMULHW:
- return int32(OPVCC(31, 75, 0, 0))
- case AMULHWCC:
- return int32(OPVCC(31, 75, 0, 1))
- case AMULHWU:
- return int32(OPVCC(31, 11, 0, 0))
- case AMULHWUCC:
- return int32(OPVCC(31, 11, 0, 1))
- case AMULLW:
- return int32(OPVCC(31, 235, 0, 0))
- case AMULLWCC:
- return int32(OPVCC(31, 235, 0, 1))
- case AMULLWV:
- return int32(OPVCC(31, 235, 1, 0))
- case AMULLWVCC:
- return int32(OPVCC(31, 235, 1, 1))
-
- case AMULHD:
- return int32(OPVCC(31, 73, 0, 0))
- case AMULHDCC:
- return int32(OPVCC(31, 73, 0, 1))
- case AMULHDU:
- return int32(OPVCC(31, 9, 0, 0))
- case AMULHDUCC:
- return int32(OPVCC(31, 9, 0, 1))
- case AMULLD:
- return int32(OPVCC(31, 233, 0, 0))
- case AMULLDCC:
- return int32(OPVCC(31, 233, 0, 1))
- case AMULLDV:
- return int32(OPVCC(31, 233, 1, 0))
- case AMULLDVCC:
- return int32(OPVCC(31, 233, 1, 1))
-
- case ANAND:
- return int32(OPVCC(31, 476, 0, 0))
- case ANANDCC:
- return int32(OPVCC(31, 476, 0, 1))
- case ANEG:
- return int32(OPVCC(31, 104, 0, 0))
- case ANEGCC:
- return int32(OPVCC(31, 104, 0, 1))
- case ANEGV:
- return int32(OPVCC(31, 104, 1, 0))
- case ANEGVCC:
- return int32(OPVCC(31, 104, 1, 1))
- case ANOR:
- return int32(OPVCC(31, 124, 0, 0))
- case ANORCC:
- return int32(OPVCC(31, 124, 0, 1))
+ return OP(4, 4)
case AOR:
- return int32(OPVCC(31, 444, 0, 0))
- case AORCC:
- return int32(OPVCC(31, 444, 0, 1))
- case AORN:
- return int32(OPVCC(31, 412, 0, 0))
- case AORNCC:
- return int32(OPVCC(31, 412, 0, 1))
-
- case ARFI:
- return int32(OPVCC(19, 50, 0, 0))
- case ARFCI:
- return int32(OPVCC(19, 51, 0, 0))
- case ARFID:
- return int32(OPVCC(19, 18, 0, 0))
- case AHRFID:
- return int32(OPVCC(19, 274, 0, 0))
-
- case ARLWMI:
- return int32(OPVCC(20, 0, 0, 0))
- case ARLWMICC:
- return int32(OPVCC(20, 0, 0, 1))
- case ARLWNM:
- return int32(OPVCC(23, 0, 0, 0))
- case ARLWNMCC:
- return int32(OPVCC(23, 0, 0, 1))
-
- case ARLDCL:
- return int32(OPVCC(30, 8, 0, 0))
- case ARLDCR:
- return int32(OPVCC(30, 9, 0, 0))
-
- case ASYSCALL:
- return int32(OPVCC(17, 1, 0, 0))
-
- case ASLW:
- return int32(OPVCC(31, 24, 0, 0))
- case ASLWCC:
- return int32(OPVCC(31, 24, 0, 1))
- case ASLD:
- return int32(OPVCC(31, 27, 0, 0))
- case ASLDCC:
- return int32(OPVCC(31, 27, 0, 1))
-
- case ASRAW:
- return int32(OPVCC(31, 792, 0, 0))
- case ASRAWCC:
- return int32(OPVCC(31, 792, 0, 1))
- case ASRAD:
- return int32(OPVCC(31, 794, 0, 0))
- case ASRADCC:
- return int32(OPVCC(31, 794, 0, 1))
-
- case ASRW:
- return int32(OPVCC(31, 536, 0, 0))
- case ASRWCC:
- return int32(OPVCC(31, 536, 0, 1))
- case ASRD:
- return int32(OPVCC(31, 539, 0, 0))
- case ASRDCC:
- return int32(OPVCC(31, 539, 0, 1))
-
+ return OP(4, 5)
+ case AXOR:
+ return OP(4, 6)
case ASUB:
- return int32(OPVCC(31, 40, 0, 0))
- case ASUBCC:
- return int32(OPVCC(31, 40, 0, 1))
+ return OP(4, 2)
+ case ASUBU:
+ return OP(4, 3)
+ case ANOR:
+ return OP(4, 7)
+ case ASLL:
+ return OP(0, 4)
+ case ASRL:
+ return OP(0, 6)
+ case ASRA:
+ return OP(0, 7)
+ case ASLLV:
+ return OP(2, 4)
+ case ASRLV:
+ return OP(2, 6)
+ case ASRAV:
+ return OP(2, 7)
+ case AADDV:
+ return OP(5, 4)
+ case AADDVU:
+ return OP(5, 5)
case ASUBV:
- return int32(OPVCC(31, 40, 1, 0))
- case ASUBVCC:
- return int32(OPVCC(31, 40, 1, 1))
- case ASUBC:
- return int32(OPVCC(31, 8, 0, 0))
- case ASUBCCC:
- return int32(OPVCC(31, 8, 0, 1))
- case ASUBCV:
- return int32(OPVCC(31, 8, 1, 0))
- case ASUBCVCC:
- return int32(OPVCC(31, 8, 1, 1))
- case ASUBE:
- return int32(OPVCC(31, 136, 0, 0))
- case ASUBECC:
- return int32(OPVCC(31, 136, 0, 1))
- case ASUBEV:
- return int32(OPVCC(31, 136, 1, 0))
- case ASUBEVCC:
- return int32(OPVCC(31, 136, 1, 1))
- case ASUBME:
- return int32(OPVCC(31, 232, 0, 0))
- case ASUBMECC:
- return int32(OPVCC(31, 232, 0, 1))
- case ASUBMEV:
- return int32(OPVCC(31, 232, 1, 0))
- case ASUBMEVCC:
- return int32(OPVCC(31, 232, 1, 1))
- case ASUBZE:
- return int32(OPVCC(31, 200, 0, 0))
- case ASUBZECC:
- return int32(OPVCC(31, 200, 0, 1))
- case ASUBZEV:
- return int32(OPVCC(31, 200, 1, 0))
- case ASUBZEVCC:
- return int32(OPVCC(31, 200, 1, 1))
-
- case ASYNC:
- return int32(OPVCC(31, 598, 0, 0))
- case APTESYNC:
- return int32(OPVCC(31, 598, 0, 0) | 2<<21)
-
- case ATLBIE:
- return int32(OPVCC(31, 306, 0, 0))
- case ATLBIEL:
- return int32(OPVCC(31, 274, 0, 0))
- case ATLBSYNC:
- return int32(OPVCC(31, 566, 0, 0))
- case ASLBIA:
- return int32(OPVCC(31, 498, 0, 0))
- case ASLBIE:
- return int32(OPVCC(31, 434, 0, 0))
- case ASLBMFEE:
- return int32(OPVCC(31, 915, 0, 0))
- case ASLBMFEV:
- return int32(OPVCC(31, 851, 0, 0))
- case ASLBMTE:
- return int32(OPVCC(31, 402, 0, 0))
-
- case ATW:
- return int32(OPVCC(31, 4, 0, 0))
- case ATD:
- return int32(OPVCC(31, 68, 0, 0))
-
- case AXOR:
- return int32(OPVCC(31, 316, 0, 0))
- case AXORCC:
- return int32(OPVCC(31, 316, 0, 1))
+ return OP(5, 6)
+ case ASUBVU:
+ return OP(5, 7)
+ case AREM,
+ ADIV:
+ return OP(3, 2)
+ case AREMU,
+ ADIVU:
+ return OP(3, 3)
+ case AMUL:
+ return OP(3, 0)
+ case AMULU:
+ return OP(3, 1)
+ case AREMV,
+ ADIVV:
+ return OP(3, 6)
+ case AREMVU,
+ ADIVVU:
+ return OP(3, 7)
+ case AMULV:
+ return OP(3, 4)
+ case AMULVU:
+ return OP(3, 5)
+
+ case AJMP:
+ return OP(1, 0)
+ case AJAL:
+ return OP(1, 1)
+
+ case ABREAK:
+ return OP(1, 5)
+ case ASYSCALL:
+ return OP(1, 4)
+ case ATLBP:
+ return MMU(1, 0)
+ case ATLBR:
+ return MMU(0, 1)
+ case ATLBWI:
+ return MMU(0, 2)
+ case ATLBWR:
+ return MMU(0, 6)
+ case ARFE:
+ return MMU(2, 0)
+
+ case ADIVF:
+ return FPF(0, 3)
+ case ADIVD:
+ return FPD(0, 3)
+ case AMULF:
+ return FPF(0, 2)
+ case AMULD:
+ return FPD(0, 2)
+ case ASUBF:
+ return FPF(0, 1)
+ case ASUBD:
+ return FPD(0, 1)
+ case AADDF:
+ return FPF(0, 0)
+ case AADDD:
+ return FPD(0, 0)
+ case ATRUNCFV:
+ return FPF(1, 1)
+ case ATRUNCDV:
+ return FPD(1, 1)
+ case ATRUNCFW:
+ return FPF(1, 5)
+ case ATRUNCDW:
+ return FPD(1, 5)
+ case AMOVFV:
+ return FPF(4, 5)
+ case AMOVDV:
+ return FPD(4, 5)
+ case AMOVVF:
+ return FPV(4, 0)
+ case AMOVVD:
+ return FPV(4, 1)
+ case AMOVFW:
+ return FPF(4, 4)
+ case AMOVDW:
+ return FPD(4, 4)
+ case AMOVWF:
+ return FPW(4, 0)
+ case AMOVDF:
+ return FPD(4, 0)
+ case AMOVWD:
+ return FPW(4, 1)
+ case AMOVFD:
+ return FPF(4, 1)
+ case AABSF:
+ return FPF(0, 5)
+ case AABSD:
+ return FPD(0, 5)
+ case AMOVF:
+ return FPF(0, 6)
+ case AMOVD:
+ return FPD(0, 6)
+ case ANEGF:
+ return FPF(0, 7)
+ case ANEGD:
+ return FPD(0, 7)
+ case ACMPEQF:
+ return FPF(6, 2)
+ case ACMPEQD:
+ return FPD(6, 2)
+ case ACMPGTF:
+ return FPF(7, 4)
+ case ACMPGTD:
+ return FPD(7, 4)
+ case ACMPGEF:
+ return FPF(7, 6)
+ case ACMPGED:
+ return FPD(7, 6)
}
- ctxt.Diag("bad r/r opcode %v", obj.Aconv(a))
+ if a >= ALAST {
+ ctxt.Diag("bad rrr opcode %v+ALAST", obj.Aconv(a-ALAST))
+ } else {
+ ctxt.Diag("bad rrr opcode %v", obj.Aconv(a))
+ }
return 0
}
-func opirr(ctxt *obj.Link, a int) int32 {
+func opirr(ctxt *obj.Link, a int) uint32 {
switch a {
case AADD:
- return int32(OPVCC(14, 0, 0, 0))
- case AADDC:
- return int32(OPVCC(12, 0, 0, 0))
- case AADDCCC:
- return int32(OPVCC(13, 0, 0, 0))
- case AADD + ALAST:
- return int32(OPVCC(15, 0, 0, 0)) /* ADDIS/CAU */
-
- case AANDCC:
- return int32(OPVCC(28, 0, 0, 0))
- case AANDCC + ALAST:
- return int32(OPVCC(29, 0, 0, 0)) /* ANDIS./ANDIU. */
-
- case ABR:
- return int32(OPVCC(18, 0, 0, 0))
- case ABL:
- return int32(OPVCC(18, 0, 0, 0) | 1)
- case obj.ADUFFZERO:
- return int32(OPVCC(18, 0, 0, 0) | 1)
- case obj.ADUFFCOPY:
- return int32(OPVCC(18, 0, 0, 0) | 1)
- case ABC:
- return int32(OPVCC(16, 0, 0, 0))
- case ABCL:
- return int32(OPVCC(16, 0, 0, 0) | 1)
-
- case ABEQ:
- return int32(AOP_RRR(16<<26, 12, 2, 0))
- case ABGE:
- return int32(AOP_RRR(16<<26, 4, 0, 0))
- case ABGT:
- return int32(AOP_RRR(16<<26, 12, 1, 0))
- case ABLE:
- return int32(AOP_RRR(16<<26, 4, 1, 0))
- case ABLT:
- return int32(AOP_RRR(16<<26, 12, 0, 0))
- case ABNE:
- return int32(AOP_RRR(16<<26, 4, 2, 0))
- case ABVC:
- return int32(AOP_RRR(16<<26, 4, 3, 0))
- case ABVS:
- return int32(AOP_RRR(16<<26, 12, 3, 0))
-
- case ACMP:
- return int32(OPVCC(11, 0, 0, 0) | 1<<21) /* L=1 */
- case ACMPU:
- return int32(OPVCC(10, 0, 0, 0) | 1<<21)
- case ACMPW:
- return int32(OPVCC(11, 0, 0, 0)) /* L=0 */
- case ACMPWU:
- return int32(OPVCC(10, 0, 0, 0))
- case ALSW:
- return int32(OPVCC(31, 597, 0, 0))
-
- case AMULLW:
- return int32(OPVCC(7, 0, 0, 0))
-
+ return SP(1, 0)
+ case AADDU:
+ return SP(1, 1)
+ case ASGT:
+ return SP(1, 2)
+ case ASGTU:
+ return SP(1, 3)
+ case AAND:
+ return SP(1, 4)
case AOR:
- return int32(OPVCC(24, 0, 0, 0))
- case AOR + ALAST:
- return int32(OPVCC(25, 0, 0, 0)) /* ORIS/ORIU */
-
- case ARLWMI:
- return int32(OPVCC(20, 0, 0, 0)) /* rlwimi */
- case ARLWMICC:
- return int32(OPVCC(20, 0, 0, 1))
- case ARLDMI:
- return int32(OPVCC(30, 0, 0, 0) | 3<<2) /* rldimi */
- case ARLDMICC:
- return int32(OPVCC(30, 0, 0, 1) | 3<<2)
-
- case ARLWNM:
- return int32(OPVCC(21, 0, 0, 0)) /* rlwinm */
- case ARLWNMCC:
- return int32(OPVCC(21, 0, 0, 1))
-
- case ARLDCL:
- return int32(OPVCC(30, 0, 0, 0)) /* rldicl */
- case ARLDCLCC:
- return int32(OPVCC(30, 0, 0, 1))
- case ARLDCR:
- return int32(OPVCC(30, 1, 0, 0)) /* rldicr */
- case ARLDCRCC:
- return int32(OPVCC(30, 1, 0, 1))
- case ARLDC:
- return int32(OPVCC(30, 0, 0, 0) | 2<<2)
- case ARLDCCC:
- return int32(OPVCC(30, 0, 0, 1) | 2<<2)
-
- case ASRAW:
- return int32(OPVCC(31, 824, 0, 0))
- case ASRAWCC:
- return int32(OPVCC(31, 824, 0, 1))
- case ASRAD:
- return int32(OPVCC(31, (413 << 1), 0, 0))
- case ASRADCC:
- return int32(OPVCC(31, (413 << 1), 0, 1))
-
- case ASTSW:
- return int32(OPVCC(31, 725, 0, 0))
-
- case ASUBC:
- return int32(OPVCC(8, 0, 0, 0))
-
- case ATW:
- return int32(OPVCC(3, 0, 0, 0))
- case ATD:
- return int32(OPVCC(2, 0, 0, 0))
-
+ return SP(1, 5)
case AXOR:
- return int32(OPVCC(26, 0, 0, 0)) /* XORIL */
- case AXOR + ALAST:
- return int32(OPVCC(27, 0, 0, 0)) /* XORIU */
- }
-
- ctxt.Diag("bad opcode i/r %v", obj.Aconv(a))
- return 0
-}
-
-/*
- * load o(a),d
- */
-func opload(ctxt *obj.Link, a int) int32 {
- switch a {
- case AMOVD:
- return int32(OPVCC(58, 0, 0, 0)) /* ld */
- case AMOVDU:
- return int32(OPVCC(58, 0, 0, 1)) /* ldu */
- case AMOVWZ:
- return int32(OPVCC(32, 0, 0, 0)) /* lwz */
- case AMOVWZU:
- return int32(OPVCC(33, 0, 0, 0)) /* lwzu */
- case AMOVW:
- return int32(OPVCC(58, 0, 0, 0) | 1<<1) /* lwa */
-
- /* no AMOVWU */
- case AMOVB, AMOVBZ:
- return int32(OPVCC(34, 0, 0, 0))
- /* load */
-
- case AMOVBU, AMOVBZU:
- return int32(OPVCC(35, 0, 0, 0))
- case AFMOVD:
- return int32(OPVCC(50, 0, 0, 0))
- case AFMOVDU:
- return int32(OPVCC(51, 0, 0, 0))
- case AFMOVS:
- return int32(OPVCC(48, 0, 0, 0))
- case AFMOVSU:
- return int32(OPVCC(49, 0, 0, 0))
- case AMOVH:
- return int32(OPVCC(42, 0, 0, 0))
- case AMOVHU:
- return int32(OPVCC(43, 0, 0, 0))
- case AMOVHZ:
- return int32(OPVCC(40, 0, 0, 0))
- case AMOVHZU:
- return int32(OPVCC(41, 0, 0, 0))
- case AMOVMW:
- return int32(OPVCC(46, 0, 0, 0)) /* lmw */
- }
-
- ctxt.Diag("bad load opcode %v", obj.Aconv(a))
- return 0
-}
-
-/*
- * indexed load a(b),d
- */
-func oploadx(ctxt *obj.Link, a int) int32 {
- switch a {
- case AMOVWZ:
- return int32(OPVCC(31, 23, 0, 0)) /* lwzx */
- case AMOVWZU:
- return int32(OPVCC(31, 55, 0, 0)) /* lwzux */
- case AMOVW:
- return int32(OPVCC(31, 341, 0, 0)) /* lwax */
- case AMOVWU:
- return int32(OPVCC(31, 373, 0, 0)) /* lwaux */
-
- case AMOVB, AMOVBZ:
- return int32(OPVCC(31, 87, 0, 0)) /* lbzx */
-
- case AMOVBU, AMOVBZU:
- return int32(OPVCC(31, 119, 0, 0)) /* lbzux */
- case AFMOVD:
- return int32(OPVCC(31, 599, 0, 0)) /* lfdx */
- case AFMOVDU:
- return int32(OPVCC(31, 631, 0, 0)) /* lfdux */
- case AFMOVS:
- return int32(OPVCC(31, 535, 0, 0)) /* lfsx */
- case AFMOVSU:
- return int32(OPVCC(31, 567, 0, 0)) /* lfsux */
- case AMOVH:
- return int32(OPVCC(31, 343, 0, 0)) /* lhax */
- case AMOVHU:
- return int32(OPVCC(31, 375, 0, 0)) /* lhaux */
- case AMOVHBR:
- return int32(OPVCC(31, 790, 0, 0)) /* lhbrx */
- case AMOVWBR:
- return int32(OPVCC(31, 534, 0, 0)) /* lwbrx */
- case AMOVHZ:
- return int32(OPVCC(31, 279, 0, 0)) /* lhzx */
- case AMOVHZU:
- return int32(OPVCC(31, 311, 0, 0)) /* lhzux */
- case AECIWX:
- return int32(OPVCC(31, 310, 0, 0)) /* eciwx */
- case ALWAR:
- return int32(OPVCC(31, 20, 0, 0)) /* lwarx */
- case ALDAR:
- return int32(OPVCC(31, 84, 0, 0))
- case ALSW:
- return int32(OPVCC(31, 533, 0, 0)) /* lswx */
+ return SP(1, 6)
+ case ALAST:
+ return SP(1, 7) /* lui */
+ case ASLL:
+ return OP(0, 0)
+ case ASRL:
+ return OP(0, 2)
+ case ASRA:
+ return OP(0, 3)
+ case AADDV:
+ return SP(3, 0)
+ case AADDVU:
+ return SP(3, 1)
+
+ case AJMP:
+ return SP(0, 2)
+ case AJAL,
+ obj.ADUFFZERO,
+ obj.ADUFFCOPY:
+ return SP(0, 3)
+ case ABEQ:
+ return SP(0, 4)
+ case ABEQ + ALAST:
+ return SP(2, 4) /* likely */
+ case ABNE:
+ return SP(0, 5)
+ case ABNE + ALAST:
+ return SP(2, 5) /* likely */
+ case ABGEZ:
+ return SP(0, 1) | BCOND(0, 1)
+ case ABGEZ + ALAST:
+ return SP(0, 1) | BCOND(0, 3) /* likely */
+ case ABGEZAL:
+ return SP(0, 1) | BCOND(2, 1)
+ case ABGEZAL + ALAST:
+ return SP(0, 1) | BCOND(2, 3) /* likely */
+ case ABGTZ:
+ return SP(0, 7)
+ case ABGTZ + ALAST:
+ return SP(2, 7) /* likely */
+ case ABLEZ:
+ return SP(0, 6)
+ case ABLEZ + ALAST:
+ return SP(2, 6) /* likely */
+ case ABLTZ:
+ return SP(0, 1) | BCOND(0, 0)
+ case ABLTZ + ALAST:
+ return SP(0, 1) | BCOND(0, 2) /* likely */
+ case ABLTZAL:
+ return SP(0, 1) | BCOND(2, 0)
+ case ABLTZAL + ALAST:
+ return SP(0, 1) | BCOND(2, 2) /* likely */
+ case ABFPT:
+ return SP(2, 1) | (257 << 16)
+ case ABFPT + ALAST:
+ return SP(2, 1) | (259 << 16) /* likely */
+ case ABFPF:
+ return SP(2, 1) | (256 << 16)
+ case ABFPF + ALAST:
+ return SP(2, 1) | (258 << 16) /* likely */
+
+ case AMOVB,
+ AMOVBU:
+ return SP(5, 0)
+ case AMOVH,
+ AMOVHU:
+ return SP(5, 1)
+ case AMOVW,
+ AMOVWU:
+ return SP(5, 3)
+ case AMOVV:
+ return SP(7, 7)
+ case AMOVF:
+ return SP(7, 1)
case AMOVD:
- return int32(OPVCC(31, 21, 0, 0)) /* ldx */
- case AMOVDU:
- return int32(OPVCC(31, 53, 0, 0)) /* ldux */
+ return SP(7, 5)
+ case AMOVWL:
+ return SP(5, 2)
+ case AMOVWR:
+ return SP(5, 6)
+ case AMOVVL:
+ return SP(5, 4)
+ case AMOVVR:
+ return SP(5, 5)
+
+ case ABREAK:
+ return SP(5, 7)
+
+ case AMOVWL + ALAST:
+ return SP(4, 2)
+ case AMOVWR + ALAST:
+ return SP(4, 6)
+ case AMOVVL + ALAST:
+ return SP(3, 2)
+ case AMOVVR + ALAST:
+ return SP(3, 3)
+ case AMOVB + ALAST:
+ return SP(4, 0)
+ case AMOVBU + ALAST:
+ return SP(4, 4)
+ case AMOVH + ALAST:
+ return SP(4, 1)
+ case AMOVHU + ALAST:
+ return SP(4, 5)
+ case AMOVW + ALAST:
+ return SP(4, 3)
+ case AMOVWU + ALAST:
+ return SP(4, 7)
+ case AMOVV + ALAST:
+ return SP(6, 7)
+ case AMOVF + ALAST:
+ return SP(6, 1)
+ case AMOVD + ALAST:
+ return SP(6, 5)
+
+ case ASLLV:
+ return OP(7, 0)
+ case ASRLV:
+ return OP(7, 2)
+ case ASRAV:
+ return OP(7, 3)
+ case ASLLV + ALAST:
+ return OP(7, 4)
+ case ASRLV + ALAST:
+ return OP(7, 6)
+ case ASRAV + ALAST:
+ return OP(7, 7)
}
- ctxt.Diag("bad loadx opcode %v", obj.Aconv(a))
- return 0
-}
-
-/*
- * store s,o(d)
- */
-func opstore(ctxt *obj.Link, a int) int32 {
- switch a {
- case AMOVB, AMOVBZ:
- return int32(OPVCC(38, 0, 0, 0)) /* stb */
-
- case AMOVBU, AMOVBZU:
- return int32(OPVCC(39, 0, 0, 0)) /* stbu */
- case AFMOVD:
- return int32(OPVCC(54, 0, 0, 0)) /* stfd */
- case AFMOVDU:
- return int32(OPVCC(55, 0, 0, 0)) /* stfdu */
- case AFMOVS:
- return int32(OPVCC(52, 0, 0, 0)) /* stfs */
- case AFMOVSU:
- return int32(OPVCC(53, 0, 0, 0)) /* stfsu */
-
- case AMOVHZ, AMOVH:
- return int32(OPVCC(44, 0, 0, 0)) /* sth */
-
- case AMOVHZU, AMOVHU:
- return int32(OPVCC(45, 0, 0, 0)) /* sthu */
- case AMOVMW:
- return int32(OPVCC(47, 0, 0, 0)) /* stmw */
- case ASTSW:
- return int32(OPVCC(31, 725, 0, 0)) /* stswi */
-
- case AMOVWZ, AMOVW:
- return int32(OPVCC(36, 0, 0, 0)) /* stw */
-
- case AMOVWZU, AMOVWU:
- return int32(OPVCC(37, 0, 0, 0)) /* stwu */
- case AMOVD:
- return int32(OPVCC(62, 0, 0, 0)) /* std */
- case AMOVDU:
- return int32(OPVCC(62, 0, 0, 1)) /* stdu */
+ if a >= ALAST {
+ ctxt.Diag("bad irr opcode %v+ALAST", obj.Aconv(a-ALAST))
+ } else {
+ ctxt.Diag("bad irr opcode %v", obj.Aconv(a))
}
-
- ctxt.Diag("unknown store opcode %v", obj.Aconv(a))
return 0
}
-/*
- * indexed store s,a(b)
- */
-func opstorex(ctxt *obj.Link, a int) int32 {
+func vshift(a int16) bool {
switch a {
- case AMOVB, AMOVBZ:
- return int32(OPVCC(31, 215, 0, 0)) /* stbx */
-
- case AMOVBU, AMOVBZU:
- return int32(OPVCC(31, 247, 0, 0)) /* stbux */
- case AFMOVD:
- return int32(OPVCC(31, 727, 0, 0)) /* stfdx */
- case AFMOVDU:
- return int32(OPVCC(31, 759, 0, 0)) /* stfdux */
- case AFMOVS:
- return int32(OPVCC(31, 663, 0, 0)) /* stfsx */
- case AFMOVSU:
- return int32(OPVCC(31, 695, 0, 0)) /* stfsux */
-
- case AMOVHZ, AMOVH:
- return int32(OPVCC(31, 407, 0, 0)) /* sthx */
- case AMOVHBR:
- return int32(OPVCC(31, 918, 0, 0)) /* sthbrx */
-
- case AMOVHZU, AMOVHU:
- return int32(OPVCC(31, 439, 0, 0)) /* sthux */
-
- case AMOVWZ, AMOVW:
- return int32(OPVCC(31, 151, 0, 0)) /* stwx */
-
- case AMOVWZU, AMOVWU:
- return int32(OPVCC(31, 183, 0, 0)) /* stwux */
- case ASTSW:
- return int32(OPVCC(31, 661, 0, 0)) /* stswx */
- case AMOVWBR:
- return int32(OPVCC(31, 662, 0, 0)) /* stwbrx */
- case ASTWCCC:
- return int32(OPVCC(31, 150, 0, 1)) /* stwcx. */
- case ASTDCCC:
- return int32(OPVCC(31, 214, 0, 1)) /* stwdx. */
- case AECOWX:
- return int32(OPVCC(31, 438, 0, 0)) /* ecowx */
- case AMOVD:
- return int32(OPVCC(31, 149, 0, 0)) /* stdx */
- case AMOVDU:
- return int32(OPVCC(31, 181, 0, 0)) /* stdux */
+ case ASLLV,
+ ASRLV,
+ ASRAV:
+ return true
}
-
- ctxt.Diag("unknown storex opcode %v", obj.Aconv(a))
- return 0
+ return false
}