From: Richard Sandiford Date: Wed, 9 Mar 2005 09:39:31 +0000 (+0000) Subject: * config/tc-mips.c (MAX_VR4130_NOPS, MAX_DELAY_NOPS): New macros. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7d8e00cf78a71a5a319f43d030597edfe01c266d;p=binutils-gdb.git * config/tc-mips.c (MAX_VR4130_NOPS, MAX_DELAY_NOPS): New macros. (MAX_NOPS): Bump to 4. (mips_fix_vr4130): New variable. (nops_for_vr4130): New function. (nops_for_insn): Use MAX_DELAY_NOPS rather than MAX_NOPS. Use nops_for_vr4130 if working around VR4130 errata. (OPTION_FIX_VR4130, OPTION_NO_FIX_VR4130): New macros. (md_longopts): Add -mfix-vr4130 and -mno-fix-vr4130. (md_parse_option): Handle them. (md_show_usage): Print them. * doc/c-mips.texi: Document -mfix-vr4130 and -mno-fix-vr4130. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index d020a8f551c..cf373d82818 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2005-03-09 Richard Sandiford + + * config/tc-mips.c (MAX_VR4130_NOPS, MAX_DELAY_NOPS): New macros. + (MAX_NOPS): Bump to 4. + (mips_fix_vr4130): New variable. + (nops_for_vr4130): New function. + (nops_for_insn): Use MAX_DELAY_NOPS rather than MAX_NOPS. Use + nops_for_vr4130 if working around VR4130 errata. + (OPTION_FIX_VR4130, OPTION_NO_FIX_VR4130): New macros. + (md_longopts): Add -mfix-vr4130 and -mno-fix-vr4130. + (md_parse_option): Handle them. + (md_show_usage): Print them. + * doc/c-mips.texi: Document -mfix-vr4130 and -mno-fix-vr4130. + 2005-03-09 Richard Sandiford * config/tc-mips.c (append_insn): Remove cop_interlocks test from diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 021dd4030b3..c16125bf134 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -557,9 +557,14 @@ static int mips_optimize = 2; equivalent to seeing no -g option at all. */ static int mips_debug = 0; -/* The maximum number of NOPs needed to satisfy a hardware hazard - or processor errata. */ -#define MAX_NOPS 2 +/* The maximum number of NOPs needed to avoid the VR4130 mflo/mfhi errata. */ +#define MAX_VR4130_NOPS 4 + +/* The maximum number of NOPs needed to fill delay slots. */ +#define MAX_DELAY_NOPS 2 + +/* The maximum number of NOPs needed for any purpose. */ +#define MAX_NOPS 4 /* A list of previous instructions, with index 0 being the most recent. We need to look back MAX_NOPS instructions when filling delay slots @@ -659,6 +664,9 @@ static unsigned int vr4120_conflicts[NUM_FIX_VR4120_CLASSES]; /* True if -mfix-vr4120 is in force. */ static int mips_fix_vr4120; +/* ...likewise -mfix-vr4130. */ +static int mips_fix_vr4130; + /* We don't relax branches by default, since this causes us to expand `la .l2 - .l1' if there's a branch between .l1 and .l2, because we fail to compute the offset before expanding the macro to the most @@ -2011,6 +2019,48 @@ insns_between (const struct mips_cl_insn *insn1, return 0; } +/* Return the number of nops that would be needed to work around the + VR4130 mflo/mfhi errata if instruction INSN immediately followed + the MAX_VR4130_NOPS instructions described by HISTORY. */ + +static int +nops_for_vr4130 (const struct mips_cl_insn *history, + const struct mips_cl_insn *insn) +{ + int i, j, reg; + + /* Check if the instruction writes to HI or LO. MTHI and MTLO + are not affected by the errata. */ + if (insn != 0 + && ((insn->insn_mo->pinfo & (INSN_WRITE_HI | INSN_WRITE_LO)) == 0 + || strcmp (insn->insn_mo->name, "mtlo") == 0 + || strcmp (insn->insn_mo->name, "mthi") == 0)) + return 0; + + /* Search for the first MFLO or MFHI. */ + for (i = 0; i < MAX_VR4130_NOPS; i++) + if (!history[i].noreorder_p && MF_HILO_INSN (history[i].insn_mo->pinfo)) + { + /* Extract the destination register. */ + if (mips_opts.mips16) + reg = mips16_to_32_reg_map[MIPS16_EXTRACT_OPERAND (RX, history[i])]; + else + reg = EXTRACT_OPERAND (RD, history[i]); + + /* No nops are needed if INSN reads that register. */ + if (insn != NULL && insn_uses_reg (insn, reg, MIPS_GR_REG)) + return 0; + + /* ...or if any of the intervening instructions do. */ + for (j = 0; j < i; j++) + if (insn_uses_reg (&history[j], reg, MIPS_GR_REG)) + return 0; + + return MAX_VR4130_NOPS - i; + } + return 0; +} + /* Return the number of nops that would be needed if instruction INSN immediately followed the MAX_NOPS instructions given by HISTORY, where HISTORY[0] is the most recent instruction. If INSN is null, @@ -2023,13 +2073,21 @@ nops_for_insn (const struct mips_cl_insn *history, int i, nops, tmp_nops; nops = 0; - for (i = 0; i < MAX_NOPS; i++) + for (i = 0; i < MAX_DELAY_NOPS; i++) if (!history[i].noreorder_p) { tmp_nops = insns_between (history + i, insn) - i; if (tmp_nops > nops) nops = tmp_nops; } + + if (mips_fix_vr4130) + { + tmp_nops = nops_for_vr4130 (history, insn); + if (tmp_nops > nops) + nops = tmp_nops; + } + return nops; } @@ -9966,9 +10024,13 @@ struct option md_longopts[] = #define OPTION_NO_FIX_VR4120 (OPTION_FIX_BASE + 3) {"mfix-vr4120", no_argument, NULL, OPTION_FIX_VR4120}, {"mno-fix-vr4120", no_argument, NULL, OPTION_NO_FIX_VR4120}, +#define OPTION_FIX_VR4130 (OPTION_FIX_BASE + 4) +#define OPTION_NO_FIX_VR4130 (OPTION_FIX_BASE + 5) + {"mfix-vr4130", no_argument, NULL, OPTION_FIX_VR4130}, + {"mno-fix-vr4130", no_argument, NULL, OPTION_NO_FIX_VR4130}, /* Miscellaneous options. */ -#define OPTION_MISC_BASE (OPTION_FIX_BASE + 4) +#define OPTION_MISC_BASE (OPTION_FIX_BASE + 6) #define OPTION_TRAP (OPTION_MISC_BASE + 0) {"trap", no_argument, NULL, OPTION_TRAP}, {"no-break", no_argument, NULL, OPTION_TRAP}, @@ -10211,6 +10273,14 @@ md_parse_option (int c, char *arg) mips_fix_vr4120 = 0; break; + case OPTION_FIX_VR4130: + mips_fix_vr4130 = 1; + break; + + case OPTION_NO_FIX_VR4130: + mips_fix_vr4130 = 0; + break; + case OPTION_RELAX_BRANCH: mips_relax_branch = 1; break; @@ -13886,6 +13956,7 @@ MIPS options:\n\ -no-mips16 do not generate mips16 instructions\n")); fprintf (stream, _("\ -mfix-vr4120 work around certain VR4120 errata\n\ +-mfix-vr4130 work around VR4130 mflo/mfhi errata\n\ -mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\ -mfp32 use 32-bit FPRs, regardless of the chosen ISA\n\ -mno-shared optimize output for executables\n\ diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index eb7daf62d10..733d5d7bde1 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-03-09 Richard Sandiford + + * gas/mips/vr4130.[sd]: New test. + * gas/mips/mips.exp: Run it. + 2005-03-09 Richard Sandiford * gas/mips/relax-swap1-mips[12].d: Expect the delay slots of diff --git a/gas/testsuite/gas/mips/vr4130.d b/gas/testsuite/gas/mips/vr4130.d new file mode 100644 index 00000000000..4933d4d9d29 --- /dev/null +++ b/gas/testsuite/gas/mips/vr4130.d @@ -0,0 +1,705 @@ +#as: -mfix-vr4130 -march=vr4130 -mabi=o64 +#objdump: -dz +#name: MIPS VR4130 workarounds + +.*file format.* + +Disassembly.* + +.* : +# +# PART A +# +.* mfhi .* +.* mult .* +# +.* mflo .* +.* mult .* +# +# PART B +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* nop +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +# PART C +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +# PART D +# +.* mfhi .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* nop +.* mult .* +# +# PART E +# +.* mfhi .* +.* nop +.* nop +.* bnez .* +.* nop +# +.* mfhi .* +.* addiu .* +.* nop +.* bnez .* +.* nop +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* bnez .* +.* nop +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* bnez .* +.* nop +# +# PART F +# +.* mfhi .* +.* addiu .* +.* nop +.* bnez .* +.* nop +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* bnez .* +.* nop +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* bnez .* +.* addiu .* +# +# PART G +# +.* mfhi .* +.* addiu .* +.* nop +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +# PART H +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* nop +.* nop +.* addiu .* +.* mult .* +# +.* mfhi .* +.* nop +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +# PART I +# +.* mflo .* +.* nop +.* nop +.* nop +.* nop +.* mult .* +# +.* mflo .* +.* nop +.* nop +.* nop +.* nop +.* multu .* +# +.* mflo .* +.* nop +.* nop +.* nop +.* nop +.* dmult .* +# +.* mflo .* +.* nop +.* nop +.* nop +.* nop +.* dmultu .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* div .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* divu .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* ddiv .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* ddivu .* +# +# PART J +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* macc .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* macchi .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* macchis .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* macchiu .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* macchius .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* maccs .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* maccu .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* maccus .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* dmacc .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* dmacchi .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* dmacchis .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* dmacchiu .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* dmacchius .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* dmaccs .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* dmaccu .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* dmaccus .* +# +# PART K +# +.* mflo .* +.* nop +.* nop +.* mtlo .* +# +.* mflo .* +.* mthi .* +# +.* mfhi .* +.* mtlo .* +# +.* mfhi .* +.* nop +.* nop +.* mthi .* + +.* : +# +# PART A +# +.* mfhi .* +.* mult .* +# +.* mflo .* +.* mult .* +# +# PART B +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* nop +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +# PART C +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +# PART D +# +.* mfhi .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* nop +.* mult .* +# +# PART E +# +.* mfhi .* +.* nop +.* nop +.* nop +.* bnez .* +# +.* mfhi .* +.* addiu .* +.* nop +.* nop +.* bnez .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* bnez .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* bnez .* +# +# PART F +# +.* mfhi .* +.* addiu .* +.* nop +.* nop +.* bnez .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* bnez .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* bnez .* +# +# PART G +# +.* mfhi .* +.* addiu .* +.* nop +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* nop +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +# PART H +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* mult .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* nop +.* nop +.* addiu .* +.* mult .* +# +.* mfhi .* +.* nop +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +.* mfhi .* +.* addiu .* +.* addiu .* +.* addiu .* +.* addiu .* +.* mult .* +# +# PART I +# +.* mflo .* +.* nop +.* nop +.* nop +.* nop +.* mult .* +# +.* mflo .* +.* nop +.* nop +.* nop +.* nop +.* multu .* +# +.* mflo .* +.* nop +.* nop +.* nop +.* nop +.* dmult .* +# +.* mflo .* +.* nop +.* nop +.* nop +.* nop +.* dmultu .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* div .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* divu .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* ddiv .* +# +.* mfhi .* +.* nop +.* nop +.* nop +.* nop +.* ddivu .* +#pass diff --git a/gas/testsuite/gas/mips/vr4130.s b/gas/testsuite/gas/mips/vr4130.s new file mode 100644 index 00000000000..1f1dfcf04f7 --- /dev/null +++ b/gas/testsuite/gas/mips/vr4130.s @@ -0,0 +1,305 @@ + .macro check2 insn + mflo $2 + \insn $3,$3 + .endm + + .macro check3 insn + mfhi $2 + \insn $0,$3,$3 + .endm + + .macro main func + + .ent \func + .type \func,@function +\func: + + # PART A + # + # Check that mfhis and mflos in .set noreorder blocks are not + # considered. + + .set noreorder + mfhi $2 + .set reorder + mult $3,$3 + + .set noreorder + mflo $2 + .set reorder + mult $3,$3 + + # PART B + # + # Check for simple instances. + + mfhi $2 + mult $3,$3 # 4 nops + + mfhi $2 + addiu $3,1 + mult $4,$4 # 3 nops + + mfhi $2 + addiu $3,1 + addiu $4,1 + mult $5,$5 # 2 nops + + mfhi $2 + addiu $3,1 + addiu $4,1 + addiu $5,1 + mult $6,$6 # 1 nop + + mfhi $2 + addiu $3,1 + addiu $4,1 + addiu $5,1 + addiu $6,1 + mult $7,$7 # 0 nops + + # PART C + # + # Check that no nops are inserted after the result has been read. + + mfhi $2 + addiu $2,1 + addiu $3,1 + addiu $4,1 + mult $5,$5 + + mfhi $2 + addiu $3,1 + addiu $2,1 + addiu $4,1 + mult $5,$5 + + mfhi $2 + addiu $3,1 + addiu $4,1 + addiu $2,1 + mult $5,$5 + + mfhi $2 + addiu $3,1 + addiu $4,1 + addiu $5,1 + mult $2,$2 + + # PART D + # + # Check that we still insert the usual interlocking nops in cases + # where the VR4130 errata doesn't apply. + + mfhi $2 + mult $2,$2 # 2 nops + + mfhi $2 + addiu $2,1 + mult $3,$3 # 1 nop + + mfhi $2 + addiu $3,1 + mult $2,$2 # 1 nop + + # PART E + # + # Check for branches whose targets might be affected. + + mfhi $2 + bnez $3,1f # 2 nops for normal mode, 3 for mips16 + + mfhi $2 + addiu $3,1 + bnez $3,1f # 1 nop for normal mode, 2 for mips16 + + mfhi $2 + addiu $3,1 + addiu $3,1 + bnez $3,1f # 0 nops for normal mode, 1 for mips16 + + mfhi $2 + addiu $3,1 + addiu $3,1 + addiu $3,1 + bnez $3,1f # 0 nops + + # PART F + # + # As above, but with no dependencies between the branch and + # the previous instruction. The final branch can use the + # preceding addiu as its delay slot. + + mfhi $2 + addiu $3,1 + bnez $4,1f # 1 nop for normal mode, 2 for mips16 + + mfhi $2 + addiu $3,1 + addiu $4,1 + bnez $5,1f # 0 nops for normal mode, 1 for mips16 + + mfhi $2 + addiu $3,1 + addiu $4,1 + addiu $5,1 + bnez $6,1f # 0 nops, fill delay slot in normal mode +1: + + # PART G + # + # Like part B, but check that intervening .set noreorders don't + # affect the number of nops. + + mfhi $2 + .set noreorder + addiu $3,1 + .set reorder + mult $4,$4 # 3 nops + + mfhi $2 + .set noreorder + addiu $3,1 + .set reorder + addiu $4,1 + mult $5,$5 # 2 nops + + mfhi $2 + addiu $3,1 + .set noreorder + addiu $4,1 + .set reorder + mult $5,$5 # 2 nops + + mfhi $2 + .set noreorder + addiu $3,1 + addiu $4,1 + .set reorder + mult $5,$5 # 2 nops + + mfhi $2 + addiu $3,1 + .set noreorder + addiu $4,1 + .set reorder + addiu $5,1 + mult $6,$6 # 1 nop + + mfhi $2 + .set noreorder + addiu $3,1 + addiu $4,1 + addiu $5,1 + .set reorder + mult $6,$6 # 1 nop + + mfhi $2 + .set noreorder + addiu $3,1 + addiu $4,1 + addiu $5,1 + addiu $6,1 + .set reorder + mult $7,$7 # 0 nops + + # PART H + # + # Like part B, but the mult occurs in a .set noreorder block. + + mfhi $2 + .set noreorder + mult $3,$3 # 4 nops + .set reorder + + mfhi $2 + .set noreorder + addiu $3,1 + mult $4,$4 # 3 nops + .set reorder + + mfhi $2 + addiu $3,1 + .set noreorder + addiu $4,1 + mult $5,$5 # 2 nops + .set reorder + + mfhi $2 + .set noreorder + addiu $3,1 + addiu $4,1 + addiu $5,1 + mult $6,$6 # 1 nop + .set reorder + + mfhi $2 + .set noreorder + addiu $3,1 + addiu $4,1 + addiu $5,1 + addiu $6,1 + mult $7,$7 # 0 nops + .set reorder + + # PART I + # + # Check every affected multiplication and division instruction. + + check2 mult + check2 multu + check2 dmult + check2 dmultu + + check3 div + check3 divu + check3 ddiv + check3 ddivu + + .end \func + .endm + + .set nomips16 + main foo + + # PART J + # + # Check every affected multiply-accumulate instruction. + + check3 macc + check3 macchi + check3 macchis + check3 macchiu + check3 macchius + check3 maccs + check3 maccu + check3 maccus + + check3 dmacc + check3 dmacchi + check3 dmacchis + check3 dmacchiu + check3 dmacchius + check3 dmaccs + check3 dmaccu + check3 dmaccus + + # PART K + # + # Check that mtlo and mthi are exempt from the VR4130 errata, + # although the usual interlocking delay applies. + + mflo $2 + mtlo $3 + + mflo $2 + mthi $3 + + mfhi $2 + mtlo $3 + + mfhi $2 + mthi $3 + + .set mips16 + main bar