(*
 * WARNING: This file was automatically generated by MDLGen (v3.0)
 * from the machine description file "mips/mips.mdl".
 * DO NOT EDIT this file directly
 *)


functor MIPSAsmEmitter(structure S : INSTRUCTION_STREAM
                       structure Instr : MIPSINSTR
                          where T = S.P.T
                       structure Shuffle : MIPSSHUFFLE
                          where I = Instr
                       structure MLTreeEval : MLTREE_EVAL
                          where T = Instr.T
                      ) : INSTRUCTION_EMITTER =
struct
   structure I  = Instr
   structure C  = I.C
   structure T  = I.T
   structure S  = S
   structure P  = S.P
   structure Constant = I.Constant
   
   open AsmFlags
   
   fun error msg = MLRiscErrorMsg.error("MIPSAsmEmitter",msg)
   
   fun makeStream formatAnnotations =
   let val stream = !AsmStream.asmOutStream
       fun emit' s = TextIO.output(stream,s)
       val newline = ref true
       val tabs = ref 0
       fun tabbing 0 = ()
         | tabbing n = (emit' "\t"; tabbing(n-1))
       fun emit s = (tabbing(!tabs); tabs := 0; newline := false; emit' s)
       fun nl() = (tabs := 0; if !newline then () else (newline := true; emit' "\n"))
       fun comma() = emit ","
       fun tab() = tabs := 1
       fun indent() = tabs := 2
       fun ms n = let val s = Int.toString n
                  in  if n<0 then "-"^String.substring(s,1,size s-1)
                      else s
                  end
       fun emit_label lab = emit(P.Client.AsmPseudoOps.lexpToString(T.LABEL lab))
       fun emit_labexp le = emit(P.Client.AsmPseudoOps.lexpToString (T.LABEXP le))
       fun emit_const c = emit(Constant.toString c)
       fun emit_int i = emit(ms i)
       fun paren f = (emit "("; f(); emit ")")
       fun defineLabel lab = emit(P.Client.AsmPseudoOps.defineLabel lab^"\n")
       fun entryLabel lab = defineLabel lab
       fun comment msg = (tab(); emit("/* " ^ msg ^ " */"); nl())
       fun annotation a = comment(Annotations.toString a)
       fun getAnnotations() = error "getAnnotations"
       fun doNothing _ = ()
       fun fail _ = raise Fail "AsmEmitter"
       fun emit_region mem = comment(I.Region.toString mem)
       val emit_region = 
          if !show_region then emit_region else doNothing
       fun pseudoOp pOp = (emit(P.toString pOp); emit "\n")
       fun init size = (comment("Code Size = " ^ ms size); nl())
       val emitCellInfo = AsmFormatUtil.reginfo
                                (emit,formatAnnotations)
       fun emitCell r = (emit(CellsBasis.toString r); emitCellInfo r)
       fun emit_cellset(title,cellset) =
         (nl(); comment(title^CellsBasis.CellSet.toString cellset))
       val emit_cellset = 
         if !show_cellset then emit_cellset else doNothing
       fun emit_defs cellset = emit_cellset("defs: ",cellset)
       fun emit_uses cellset = emit_cellset("uses: ",cellset)
       val emit_cutsTo = 
         if !show_cutsTo then AsmFormatUtil.emit_cutsTo emit
         else doNothing
       fun emitter instr =
       let
   fun asm_load (I.LD) = "ld"
     | asm_load (I.LW) = "lw"
     | asm_load (I.LH) = "lh"
     | asm_load (I.LHU) = "lhu"
     | asm_load (I.LB) = "lb"
     | asm_load (I.LBU) = "lbu"
     | asm_load (I.LWL) = "lwl"
     | asm_load (I.LWR) = "lwr"
     | asm_load (I.LWU) = "lwu"
     | asm_load (I.LDL) = "ldl"
     | asm_load (I.LDR) = "ldr"
     | asm_load (I.ULH) = "ulh"
     | asm_load (I.ULHU) = "ulhu"
     | asm_load (I.ULW) = "ulw"
     | asm_load (I.ULD) = "uld"
   and emit_load x = emit (asm_load x)
   and asm_store (I.SD) = "sd"
     | asm_store (I.SW) = "sw"
     | asm_store (I.SH) = "sh"
     | asm_store (I.SB) = "sb"
     | asm_store (I.SWL) = "swl"
     | asm_store (I.SWR) = "swr"
     | asm_store (I.SDL) = "sdl"
     | asm_store (I.SDR) = "sdr"
     | asm_store (I.USH) = "ush"
     | asm_store (I.USW) = "usw"
     | asm_store (I.USD) = "usd"
   and emit_store x = emit (asm_store x)
   and asm_fload (I.LDC1) = "ldc1"
     | asm_fload (I.LWC1) = "lwc1"
   and emit_fload x = emit (asm_fload x)
   and asm_fstore (I.SDC1) = "sdc1"
     | asm_fstore (I.SWC1) = "swc1"
   and emit_fstore x = emit (asm_fstore x)
   and asm_fcond (I.FF) = "f"
     | asm_fcond (I.FUN) = "un"
     | asm_fcond (I.FEQ) = "eq"
     | asm_fcond (I.FUEQ) = "fueq"
     | asm_fcond (I.FOLT) = "folt"
     | asm_fcond (I.FULT) = "ult"
     | asm_fcond (I.FOLE) = "ole"
     | asm_fcond (I.FULE) = "ule"
     | asm_fcond (I.FNGLE) = "ngle"
     | asm_fcond (I.FSP) = "sf"
     | asm_fcond (I.FNGL) = "ngl"
     | asm_fcond (I.FSEQ) = "seq"
     | asm_fcond (I.FLT) = "flt"
     | asm_fcond (I.FNGE) = "fnge"
     | asm_fcond (I.FLE) = "le"
     | asm_fcond (I.FNGT) = "ngt"
   and emit_fcond x = emit (asm_fcond x)
   and asm_cond (I.EQ) = "eq"
     | asm_cond (I.NE) = "ne"
     | asm_cond (I.LEZ) = "lez"
     | asm_cond (I.GTZ) = "gtz"
     | asm_cond (I.LTZ) = "ltz"
     | asm_cond (I.GEZ) = "gez"
   and emit_cond x = emit (asm_cond x)
   and asm_fbranch (I.BC1T) = "bc1t"
     | asm_fbranch (I.BC1F) = "bc1f"
   and emit_fbranch x = emit (asm_fbranch x)
   and asm_likely (I.LIKELY) = "l"
     | asm_likely (I.UNLIKELY) = ""
   and emit_likely x = emit (asm_likely x)
   and asm_arith (I.ADD) = "add"
     | asm_arith (I.ADDU) = "addu"
     | asm_arith (I.AND) = "and"
     | asm_arith (I.XOR) = "xor"
     | asm_arith (I.MUL) = "mul"
     | asm_arith (I.MULO) = "mulo"
     | asm_arith (I.MULOU) = "mulou"
     | asm_arith (I.NOR) = "nor"
     | asm_arith (I.OR) = "or"
     | asm_arith (I.SEQ) = "seq"
     | asm_arith (I.SGT) = "sgt"
     | asm_arith (I.SGE) = "sge"
     | asm_arith (I.SGEU) = "sgeu"
     | asm_arith (I.SGTU) = "sgtu"
     | asm_arith (I.SLT) = "slt"
     | asm_arith (I.SLE) = "sle"
     | asm_arith (I.SLEU) = "sleu"
     | asm_arith (I.SLTU) = "sltu"
     | asm_arith (I.SNE) = "sne"
     | asm_arith (I.SUB) = "sub"
     | asm_arith (I.SUBU) = "subu"
     | asm_arith (I.REM) = "rem"
     | asm_arith (I.REMU) = "remu"
     | asm_arith (I.SRA) = "sra"
     | asm_arith (I.SLL) = "sll"
     | asm_arith (I.SRL) = "srl"
     | asm_arith (I.ROR) = "ror"
     | asm_arith (I.ROL) = "rol"
     | asm_arith (I.MOVN) = "movn"
     | asm_arith (I.MOVZ) = "movz"
     | asm_arith (I.DADD) = "dadd"
     | asm_arith (I.DADDU) = "daddu"
     | asm_arith (I.DMUL) = "dmul"
     | asm_arith (I.DMULO) = "dmulo"
     | asm_arith (I.DMULOU) = "dmulou"
     | asm_arith (I.DSUB) = "dsub"
     | asm_arith (I.DSUBU) = "dsubu"
     | asm_arith (I.DREM) = "drem"
     | asm_arith (I.DREMU) = "dremu"
     | asm_arith (I.DROL) = "drol"
     | asm_arith (I.DROR) = "dror"
     | asm_arith (I.DSLL) = "dsll"
     | asm_arith (I.DSLL32) = "dsll32"
     | asm_arith (I.DSLLV) = "dsllv"
     | asm_arith (I.DSRA) = "dsra"
     | asm_arith (I.DSRA32) = "dsra32"
     | asm_arith (I.DSRAV) = "dsrav"
     | asm_arith (I.DSRL) = "dsrl"
     | asm_arith (I.DSRL32) = "dsrl32"
     | asm_arith (I.DSRLV) = "dsrlv"
   and emit_arith x = emit (asm_arith x)
   and asm_unary (I.ABS) = "abs"
     | asm_unary (I.NEG) = "neg"
     | asm_unary (I.NEGU) = "negu"
     | asm_unary (I.NOT) = "not"
     | asm_unary (I.DABS) = "dabs"
     | asm_unary (I.DNEG) = "dneg"
     | asm_unary (I.DNEGU) = "dnegu"
   and emit_unary x = emit (asm_unary x)
   and asm_multiply (I.MULT) = "mult"
     | asm_multiply (I.MULTU) = "multu"
     | asm_multiply (I.DMULT) = "dmult"
     | asm_multiply (I.DMULTU) = "dmultu"
   and emit_multiply x = emit (asm_multiply x)
   and asm_divide (I.DIV) = "div"
     | asm_divide (I.DIVU) = "divu"
     | asm_divide (I.DDIV) = "ddiv"
     | asm_divide (I.DDIVU) = "ddivu"
   and emit_divide x = emit (asm_divide x)
   and asm_trap (I.TEQ) = "teq"
     | asm_trap (I.TNE) = "tne"
     | asm_trap (I.TLT) = "tlt"
     | asm_trap (I.TLTU) = "tltu"
     | asm_trap (I.TGE) = "tge"
     | asm_trap (I.TGEU) = "tgeu"
   and emit_trap x = emit (asm_trap x)
   and asm_farith (I.ADD_D) = "add.d"
     | asm_farith (I.ADD_S) = "add.s"
     | asm_farith (I.SUB_D) = "sub.d"
     | asm_farith (I.SUB_S) = "sub.s"
     | asm_farith (I.MUL_D) = "mul.d"
     | asm_farith (I.MUL_S) = "mul.s"
     | asm_farith (I.DIV_D) = "div.d"
     | asm_farith (I.DIV_S) = "div.s"
   and emit_farith x = emit (asm_farith x)
   and asm_funary (I.MOV_D) = "mov.d"
     | asm_funary (I.MOV_S) = "mov.s"
     | asm_funary (I.ABS_D) = "abs.d"
     | asm_funary (I.ABS_S) = "abs.s"
     | asm_funary (I.NEG_D) = "neg.d"
     | asm_funary (I.NEG_S) = "neg.s"
     | asm_funary (I.SQRT_D) = "sqrt.d"
     | asm_funary (I.SQRT_S) = "sqrt.s"
     | asm_funary (I.CVT_SD) = "cvt.s.d"
     | asm_funary (I.CVT_SW) = "cvt.s.w"
     | asm_funary (I.CVT_DS) = "cvt.d.s"
     | asm_funary (I.CVT_DW) = "cvt.d.w"
     | asm_funary (I.CVT_WS) = "cvt.w.s"
     | asm_funary (I.CVT_WD) = "cvt.w.d"
     | asm_funary (I.CVT_SL) = "cvt.s.l"
     | asm_funary (I.CVT_DL) = "cvt.d.l"
     | asm_funary (I.CVT_LS) = "cvt.l.s"
     | asm_funary (I.CVT_LD) = "cvt.l.d"
   and emit_funary x = emit (asm_funary x)
   and asm_cvti2f (I.MTC1) = "mtc1"
     | asm_cvti2f (I.DMTC1) = "dmtc1"
   and emit_cvti2f x = emit (asm_cvti2f x)
   and asm_cvtf2i (I.MFC1) = "mfc1"
     | asm_cvtf2i (I.DMFC1) = "dmfc1"
   and emit_cvtf2i x = emit (asm_cvtf2i x)
   and asm_farith3 (I.MADD_D) = "madd.d"
     | asm_farith3 (I.MADD_S) = "madd.s"
     | asm_farith3 (I.NMADD_D) = "nmadd.d"
     | asm_farith3 (I.NMADD_S) = "nmadd.s"
     | asm_farith3 (I.MSUB_D) = "msub.d"
     | asm_farith3 (I.MSUB_S) = "msub.s"
     | asm_farith3 (I.NMSUB_D) = "nmsub.d"
     | asm_farith3 (I.NMSUB_S) = "nmsub.s"
   and emit_farith3 x = emit (asm_farith3 x)
   and asm_fround (I.TRUNC_WS) = "trunc.w.s"
     | asm_fround (I.TRUNC_WD) = "trunc.w.d"
     | asm_fround (I.ROUND_WS) = "round.w.d"
     | asm_fround (I.ROUND_WD) = "round.w.d"
     | asm_fround (I.CEIL_WD) = "ceil.w.d"
     | asm_fround (I.CEIL_WS) = "ceil.w.s"
     | asm_fround (I.CEILU_WD) = "ceilu.w.d"
     | asm_fround (I.CEILU_WS) = "ceilu.w.s"
     | asm_fround (I.FLOOR_WD) = "floor.w.d"
     | asm_fround (I.FLOOR_WS) = "floor.w.s"
     | asm_fround (I.FLOORU_WD) = "flooru.w.d"
     | asm_fround (I.FLOORU_WS) = "flooru.w.s"
     | asm_fround (I.ROUNDU_WD) = "roundu.w.d"
     | asm_fround (I.ROUNDU_WS) = "roundu.w.s"
     | asm_fround (I.TRUNCU_WD) = "truncu.w.d"
     | asm_fround (I.TRUNCU_WS) = "truncu.w.s"
     | asm_fround (I.TRUNC_LS) = "trunc.l.s"
     | asm_fround (I.TRUNC_LD) = "trunc.l.d"
     | asm_fround (I.ROUND_LS) = "round.l.s"
     | asm_fround (I.ROUND_LD) = "round.l.d"
     | asm_fround (I.CEIL_LS) = "ceil.l.s"
     | asm_fround (I.CEIL_LD) = "ceil.l.d"
     | asm_fround (I.FLOOR_LS) = "floor.l.s"
     | asm_fround (I.FLOOR_LD) = "floor.l.d"
   and emit_fround x = emit (asm_fround x)
   and asm_fmt (I.SINGLE) = "s"
     | asm_fmt (I.DOUBLE) = "d"
   and emit_fmt x = emit (asm_fmt x)
   and emit_operand (I.Imm int) = emit_int int
     | emit_operand (I.Reg GP) = emitCell GP
     | emit_operand (I.Lab labexp) = emit_labexp labexp
     | emit_operand (I.HiLab labexp) = 
       ( emit "$hi("; 
         emit_labexp labexp; 
         emit ")" )
     | emit_operand (I.LoLab labexp) = 
       ( emit "$lo("; 
         emit_labexp labexp; 
         emit ")" )

(*#line 244.7 "mips/mips.mdl"*)
   fun immedSuffix (s, I.Reg _) = s
     | immedSuffix (s, _) = 
       let 
(*#line 246.15 "mips/mips.mdl"*)
           val n = String.size s
       in 
          (case String.sub (s, n - 1) of
            #"u" => (String.substring (s, 0, n - 1)) ^ "iu"
          | _ => s ^ "i"
          )
       end

(*#line 253.7 "mips/mips.mdl"*)
   fun indexed (s, I.Reg _) = 
       let 
(*#line 254.15 "mips/mips.mdl"*)
           val prefix = String.substring (s, 0, 2)

(*#line 255.15 "mips/mips.mdl"*)
           val suffix = String.substring (s, 2, 4)
       in (prefix ^ "x") ^ suffix
       end
     | indexed (s, _) = s

(*#line 260.7 "mips/mips.mdl"*)
   fun emit_nop false = ()
     | emit_nop true = emit "\n\tnop"
   fun emitInstr' instr = 
       (case instr of
         I.NOP => emit "nop"
       | I.LUI{rt, imm} => 
         ( emit "lui\t"; 
           emitCell rt; 
           emit ", "; 
           emit_operand imm )
       | I.LA{rt, b, d} => 
         ( emit "la\t"; 
           emitCell rt; 
           emit ", "; 
           emitCell b; 
           emit ", "; 
           emit_operand d )
       | I.DLA{rt, b, d} => 
         ( emit "dla\t"; 
           emitCell rt; 
           emit ", "; 
           emitCell b; 
           emit ", "; 
           emit_operand d )
       | I.LOAD{l, rt, b, d, mem} => 
         ( emit_load l; 
           emit "\t"; 
           emitCell rt; 
           emit ", "; 
           emit_operand d; 
           emit "("; 
           emitCell b; 
           emit ")"; 
           emit_region mem )
       | I.STORE{s, rs, b, d, mem} => 
         ( emit_store s; 
           emit "\t"; 
           emitCell rs; 
           emit ", "; 
           emit_operand d; 
           emit "("; 
           emitCell b; 
           emit ")"; 
           emit_region mem )
       | I.FLOAD{l, ft, b, d, mem} => 
         ( indexed (asm_fload l, d); 
           emit "\t"; 
           emitCell ft; 
           emit ", "; 
           emit_operand d; 
           emit "("; 
           emitCell b; 
           emit ")"; 
           emit_region mem )
       | I.FSTORE{s, fs, b, d, mem} => 
         ( indexed (asm_fstore s, d); 
           emit "\t"; 
           emitCell fs; 
           emit ", "; 
           emit_operand d; 
           emit "("; 
           emitCell b; 
           emit ")"; 
           emit_region mem )
       | I.FCMP{fcond, fmt, cc, fs1, fs2} => 
         ( emit "c."; 
           emit_fcond fcond; 
           emit "."; 
           emit_fmt fmt; 
           emit "\t"; 
           emitCell cc; 
           emit ", "; 
           emitCell fs1; 
           emit ", "; 
           emitCell fs2 )
       | I.TRAP{t, rs, i} => 
         ( emit_trap t; 
           emit "\t"; 
           emitCell rs; 
           emit ", "; 
           emit_operand i )
       | I.J{lab, nop} => 
         ( emit "j\t"; 
           emit_label lab; 
           emit_nop nop )
       | I.JR{rs, labels, nop} => 
         ( emit "jr\t"; 
           emitCell rs; 
           emit_nop nop )
       | I.JAL{lab, defs, uses, cutsTo, mem, nop} => 
         ( emit "jal\t"; 
           emit_label lab; 
           emit_region mem; 
           emit_defs defs; 
           emit_uses uses; 
           emit_cutsTo cutsTo; 
           emit_nop nop )
       | I.JALR{rt, rs, defs, uses, cutsTo, mem, nop} => 
         ( emit "jalr\t"; 
           emitCell rt; 
           emit ", "; 
           emitCell rs; 
           emit_region mem; 
           emit_defs defs; 
           emit_uses uses; 
           emit_cutsTo cutsTo; 
           emit_nop nop )
       | I.RET{nop} => 
         ( emit "jr\t$31"; 
           emit_nop nop )
       | I.BRANCH{likely, cond, rs, rt, lab, nop} => 
         ( emit "b"; 
           emit_cond cond; 
           emit_likely likely; 
           emit "\t"; 
           emitCell rs; 
           emit ", "; 
           emitCell rt; 
           emit ", "; 
           emit_label lab; 
           emit_nop nop )
       | I.FBRANCH{likely, fbranch, cc, lab, nop} => 
         ( emit_fbranch fbranch; 
           emit_likely likely; 
           emit "\t"; 
           emitCell cc; 
           emit ", "; 
           emit_label lab; 
           emit_nop nop )
       | I.ARITH{oper, rt, rs, i} => 
         ( immedSuffix (asm_arith oper, i); 
           emit "\t"; 
           emitCell rt; 
           emit ", "; 
           emitCell rs; 
           emit ", "; 
           emit_operand i )
       | I.UNARY{oper, rt, rs} => 
         ( emit_unary oper; 
           emit "\t"; 
           emitCell rt; 
           emit ", "; 
           emitCell rs )
       | I.MULTIPLY{oper, rt, rs} => 
         ( emit_multiply oper; 
           emit "\t"; 
           emitCell rt; 
           emit ", "; 
           emitCell rs )
       | I.DIVIDE{oper, rt, rs} => 
         ( emit_divide oper; 
           emit "\t"; 
           emitCell rt; 
           emit ", "; 
           emitCell rs )
       | I.MFLO GP => 
         ( emit "mflo\t"; 
           emitCell GP )
       | I.MTLO GP => 
         ( emit "mtlo\t"; 
           emitCell GP )
       | I.MFHI GP => 
         ( emit "mfhi\t"; 
           emitCell GP )
       | I.MTHI GP => 
         ( emit "mthi\t"; 
           emitCell GP )
       | I.BREAK int => 
         ( emit "break\t"; 
           emit_int int )
       | I.FARITH{oper, ft, fs1, fs2} => 
         ( emit_farith oper; 
           emit "\t"; 
           emitCell ft; 
           emit ", "; 
           emitCell fs1; 
           emit ", "; 
           emitCell fs2 )
       | I.FUNARY{oper, ft, fs} => 
         ( emit_funary oper; 
           emit "\t"; 
           emitCell ft; 
           emit ", "; 
           emitCell fs )
       | I.FARITH3{oper, ft, fs1, fs2, fs3} => 
         ( emit_farith3 oper; 
           emit "\t"; 
           emitCell ft; 
           emit ", "; 
           emitCell fs1; 
           emit ", "; 
           emitCell fs2; 
           emit ", "; 
           emitCell fs3 )
       | I.FROUND{oper, ft, fs1, rs2} => 
         ( emit_fround oper; 
           emit "\t"; 
           emitCell ft; 
           emit ", "; 
           emitCell fs1; 
           emit ", "; 
           emitCell fs1; 
           emit ", "; 
           emitCell rs2 )
       | I.CVTI2F{cvt, rs, ft} => 
         ( emit_cvti2f cvt; 
           emit "\t"; 
           emitCell ft; 
           emit ", "; 
           emitCell rs )
       | I.CVTF2I{cvt, fs, rt} => 
         ( emit_cvtf2i cvt; 
           emit "\t"; 
           emitCell rt; 
           emit ", "; 
           emitCell fs )
       | I.COPY{dst, src, impl, tmp} => emitInstrs (Shuffle.shuffle {tmp=tmp, 
            src=src, dst=dst})
       | I.FCOPY{dst, src, impl, tmp} => emitInstrs (Shuffle.shufflefp {tmp=tmp, 
            src=src, dst=dst})
       | I.ANNOTATION{i, a} => 
         ( comment (Annotations.toString a); 
           nl (); 
           emitInstr i )
       | I.PHI{} => emit "phi"
       | I.SOURCE{} => emit "source"
       | I.SINK{} => emit "sink"
       )
      in  tab(); emitInstr' instr; nl()
      end (* emitter *)
      and emitInstrIndented i = (indent(); emitInstr i; nl())
      and emitInstrs instrs =
           app (if !indent_copies then emitInstrIndented
                else emitInstr) instrs
   
      and emitInstr(I.ANNOTATION{i,a}) =
           ( comment(Annotations.toString a);
              nl();
              emitInstr i )
        | emitInstr(I.LIVE{regs, spilled})  = 
            comment("live= " ^ CellsBasis.CellSet.toString regs ^
                    "spilled= " ^ CellsBasis.CellSet.toString spilled)
        | emitInstr(I.KILL{regs, spilled})  = 
            comment("killed:: " ^ CellsBasis.CellSet.toString regs ^
                    "spilled:: " ^ CellsBasis.CellSet.toString spilled)
        | emitInstr(I.INSTR i) = emitter i
        | emitInstr(I.COPY{k=CellsBasis.GP, sz, src, dst, tmp}) =
           emitInstrs(Shuffle.shuffle{tmp=tmp, src=src, dst=dst})
        | emitInstr(I.COPY{k=CellsBasis.FP, sz, src, dst, tmp}) =
           emitInstrs(Shuffle.shufflefp{tmp=tmp, src=src, dst=dst})
        | emitInstr _ = error "emitInstr"
   
   in  S.STREAM{beginCluster=init,
                pseudoOp=pseudoOp,
                emit=emitInstr,
                endCluster=fail,
                defineLabel=defineLabel,
                entryLabel=entryLabel,
                comment=comment,
                exitBlock=doNothing,
                annotation=annotation,
                getAnnotations=getAnnotations
               }
   end
end

