#!
# coding: utf-8
# Copyright (C) 2016 TOPS SYSTEMS
### @file asm2s.py
### @brief ASM format source file to S format source file convertor
###
### ASM形式(ただしQVPの記述のために用いられている範囲)のソースファイルを
### topsqvp-elf_as形式のソーフファイルに変換するコンバータ
### ①行を読み取ってラベル、命令、引数にパースする
### ②疑似命令やマクロ命令など互換性のない部分を変換する
### ③機械的に変換できない部分についてはWARNING!としてコメントアウトする
###
### 読み取り途中でコメントを検出したならばコメント文字を変換し行末まで飛ばす。
###
### Contact: izumida@topscom.co.jp
###
### @author: M.Izumida
### @date: October 24, 2016
###
## v01r01 Newly created
## v01r02 v01r02 INC file support
##
# Written for Python 2.7 (NOT FOR 3.x)
#=======================================================================
# インポート宣言
from __future__ import division
import sys
import re
import argparse
import os
from datetime import datetime
#=======================================================================
# バージョン文字列
versionSTR = "asm2s.py v01r02 Tops Systems (pgm by mpi)"
#=======================================================================
# 共通サブルーチン
#-------------------------------------------------------------------
def errPrint(mes):
"""errPrint.
エラー出力へのメッセージ表示
後の始末はその後で別に書くこと
"""
sys.stderr.write(mes)
sys.stderr.write('\n')
#-------------------------------------------------------------------
def stdExceptionHandler(mes):
"""standard Exception Handler.
エラーメッセージを送出し、デバッグのための情報を出力する
"""
errPrint("Exception Captured: " + str(mes))
errPrint("0:" + str(sys.exc_info()[0]))
errPrint("1:" + str(sys.exc_info()[1]))
errPrint("2:" + str(sys.exc_info()[2]))
#-------------------------------------------------------------------
def tryIntParse(st, dval, radix=10):
"""try Parse string to Integer
文字列stをパースして整数化できれば値を返す、できなければデフォルト値dvalを返す
"""
try:
work = int(st, radix)
except:
return dval
return work
#-------------------------------------------------------------------
def repExt(fname, newext):
"""Relpace Extension
fnameの拡張子部分をnewextでリプレースした文字列を返す
"""
tempName, ext = os.path.splitext(os.path.basename(fname))
return tempName + newext
#=======================================================================
# ASMファイルリーダクラス
[ドキュメント]class asmReader:
"""ASM File Reader Class.
ASMファイルを読み取ってパースするクラス
"""
#--------------------------------------------------------------------
def __init__(self, fnam, oCls, opt):
"""ASM File Reader Constructor
コンストラクタ
"""
self.asmFname = fnam # パースするASMファイルへのパス
self.outClass = oCls # 出力先となるクラス(通常はsWriterクラス)
self.opt = opt # オプションパラメータ
#バッファ
self.lineBuffer = "" # 行一時バッファ
self.lineMax = 0 # 行一時バッファ文字数
self.linePos = 0 # 行内ポインタ
#デバッグ
self.debug = False
self.verbose = False
#--------------------------------------------------------------------
[ドキュメント] def read(self):
"""read method
ファイルから行をリードして処理するメソッド
"""
nLine = 1
try:
with open(self.asmFname, 'r') as f:
for line in f:
if self.rLine(line):
break
nLine += 1
except:
stdExceptionHandler("ERROR: in file reading = " + self.asmFname + " line#=" + str(nLine))
return False
return True
#--------------------------------------------------------------------
[ドキュメント] def rLine(self, lin):
"""Read Line method
読み取った1行を処理するメソッド
常にFalseを返す。
(エラーが定義されたらTrueを返す)
"""
if self.verbose:
print lin
if self.debug:
self.outClass.writeLine(lin.rstrip())
self.setLine(lin)
self.outClass.initLineParser()
cnt = self.skipSPACE()
tkn = self.getTOKEN()
while tkn[0] != 0:
if tkn[0]==999:
self.outClass.writeToken(tkn)
return True
if (tkn[0]==100) and (cnt == 0):
tkn[0] = 200
if not self.outClass.writeToken(tkn):
return True
cnt = self.skipSPACE()
cnt = 1
tkn = self.getTOKEN()
self.outClass.finishLineParser()
return False
#--------------------------------------------------------------------
[ドキュメント] def setLine(self, lin):
"""Set Line to line buffer
1行バッファを初期化するメソッド
"""
self.lineBuffer = lin
self.lineMax = len(lin)
self.linePos = 0
return False
#--------------------------------------------------------------------
[ドキュメント] def getCHR(self):
"""LINE BUFFER, get char
1行バッファから1文字読み出すメソッド
"""
if self.linePos < self.lineMax:
temp = self.lineBuffer[self.linePos]
self.linePos += 1
return temp
return None
#--------------------------------------------------------------------
[ドキュメント] def backCHR(self):
"""LINE BUFFER, back char
1行バッファに1文字戻すメソッド
"""
if self.linePos > 0:
self.linePos -= 1
#--------------------------------------------------------------------
[ドキュメント] def skipSPACE(self):
"""LINE BUFFER, skip space
空白文字とタブを読み飛ばすメソッド。読み飛ばした空白文字数を返す。
"""
counter = 0
while self.linePos < self.lineMax:
if (self.lineBuffer[self.linePos] == " ") or (self.lineBuffer[self.linePos] == "\t"):
self.linePos += 1
counter += 1
else:
break
return counter
#--------------------------------------------------------------------
[ドキュメント] def getTOKEN(self):
"""LINE BUFFER, get token
1行バッファの現在ポジションから1トークン読み出すメソッド
空白文字の読み飛ばしはしない
現在ポジションが行末に達していたら"EOL"を返す。
0, EOL
1, COMMENT
2, {
3, }
4, [
5, ]
6, +
7, -
8, *
9, /
10, <
11, >
12, <<
13, >>
14, <=
15, >=
16, ==
17, !=
18, :
19, $
20, ,
21, %
22, &
23, |
99, "string"
100, ID
200, LABEL
999, ERROR-Message
"""
token = [0, "EOL"]
temp = self.getCHR()
workStr = ""
if (temp is None) or (temp == "\n") or (temp == "\r"):
return token
if temp == ";":
while self.linePos < self.lineMax: #行末までの文字列をコメントとして転送
temp = self.getCHR()
if (temp is None) or (temp == "\n") or (temp == "\r"):
return [1, workStr]
workStr += temp
if temp == "{":
return [2, "{"]
if temp == "}":
return [3, "}"]
if temp == "[":
return [4, "["]
if temp == "]":
return [5, "]"]
if temp == "+":
return [6, "+"]
if temp == "-":
return [7, "-"]
if temp == "*":
return [8, "*"]
if temp == "/":
return [9, "/"]
if temp == "<":
nxt = self.getCHR()
if nxt == "<":
return [12, "<<"]
if nxt == "=":
return [14, "<="]
self.backCHR()
return [10, "<"]
if temp == ">":
nxt = self.getCHR()
if nxt == ">":
return [13, ">>"]
if nxt == "=":
return [15, ">="]
self.backCHR()
return [11, ">>"]
if temp == "=":
nxt = self.getCHR()
if nxt == "=":
return [16, "=="]
return [999, "ERROR, operator == expected."]
if temp == "!":
nxt = self.getCHR()
if nxt == "=":
return [17, "!="]
return [999, "ERROR, operator != expected."]
if temp == ":":
return [18, ":"]
if temp == "$":
return [19, "$"]
if temp == ",":
return [20, ","]
if temp == "%":
return [21, "%"]
if temp == "&":
return [22, "&"]
if temp == "|":
return [23, "|"]
if temp == '"':
if self.debug:
sys.stderr.write("\nSTRING>>>")
while self.linePos < self.lineMax:
temp = self.getCHR()
if temp == '"':
return [99, workStr]
if (temp is None) or (temp == "\n") or (temp == "\r"):
return [999, "ERROR, unexpected string end."]
else:
workStr += temp
if self.debug:
sys.stderr.write(temp)
if self.debug:
sys.stderr.write("\nID>>>")
while self.linePos < self.lineMax:
if self.debug:
sys.stderr.write(temp)
if temp.isalnum() or (temp == "_") or (temp == "."):
workStr += temp
temp = self.getCHR()
else:
self.backCHR()
break
if len(workStr) == 0:
return [999, "ERROR, unknown token charactor >" + temp + "<"]
return [100, workStr.lower()]
return None
#=======================================================================
# gas形式ソースファイルライタクラス
[ドキュメント]class gasWriter:
"""GAS Writer Class.
asmReaderのパース結果を解釈し、gas形式に変換してファイルに書くクラス
"""
#--------------------------------------------------------------------
def __init__(self, ofnam, incmode):
"""debugging Writer Constructor
コンストラクタ
"""
self.oFname = ofnam
self.inc = incmode
# 一次保存用バッファ
self.bufList = []
self.writePredef()
# 行パース用
# 0:LABEL/FirstID/# 1:":"/FirstID 2:FirstID/# 3:Second以降のID待ち 9: 行末
self.initLineParser()
self.forceComment = False #以降の行でコメント化を強制する。復帰は明示キーワードかself.release
self.release = False #1行コメント化したら復帰キーワード検出なしに復帰
self.ifNest = 0 #生きているIF疑似命令のネストカウンタ
# マクロ定義用
self.convMacroArgs = False
self.macroArgs = []
# EQU解決用
self.equKEY = ""
self.equDic = dict()
# コンバージョンエラーカウンタ
self.numWarning = 0
self.numError = 0
self.sanitized = 0
# デバッグ
self.debug = False
self.verbose = False
#--------------------------------------------------------------------
[ドキュメント] def save(self):
"""buffer Writer
バッファのライタ.
書き込み成功すれば真を返す。
"""
if self.ifNest == 1:
self.writeLine(".endif")
elif self.ifNest > 1:
self.writeLine("# WARNING!-TOO-MANY-OPEN-IF")
self.numWarning += 1
self.writeLine("# of ERROR: " + str(self.numError))
self.writeLine("# of WARNING: " + str(self.numWarning))
self.writeLine("# of SANITIZED: " + str(self.sanitized))
try:
with open(self.oFname, 'w') as f:
for lin in self.bufList:
f.write(lin)
f.write("\n")
except:
stdExceptionHandler("Error: writing gas source file = " + self.oFname)
return False
return True
#--------------------------------------------------------------------
[ドキュメント] def writeLine(self, lin, opt=False):
"""write line to buffer
行を直接バッファへ書き込むためのメソッド.
opt=Trueなら行コメントとする
"""
if opt:
lin = "#" + lin
self.bufList.append(lin)
return
#--------------------------------------------------------------------
[ドキュメント] def initLineParser(self):
"""initialize line parser
行パーサを初期化するメソッド.
"""
self.linStat = 0
self.linLabel = ""
self.linID1 = ""
self.linTemp = ""
self.argOpt = [0, 0] # [numArg, opt]
self.macroPending = False
self.listArgP = False
self.equFlag = False
self.fifoFlag = False
self.INCL = False
#--------------------------------------------------------------------
[ドキュメント] def finishLineParser(self):
"""finish line parser
行パーサを完了し、1行出力するメソッド.
"""
if self.forceComment:
self.writeLine(self.linTemp, True)
if self.release:
self.forceComment = False
self.release = False
else:
self.writeLine(self.linTemp)
#--------------------------------------------------------------------
[ドキュメント] def writeToken(self, tkn):
"""write Token to buffer
トークンをバッファへ書き込むためのメソッド.
書き込みトークンが予想外のものであれば偽を返す。
"""
if self.debug:
return self.writeRawToken(tkn)
else:
return self.lineParser(tkn)
#--------------------------------------------------------------------
[ドキュメント] def lineParser(self, tkn):
"""line parser
行パーサ
"""
#if self.verbose:
# print tkn[0], tkn[1]
if self.linStat == 0:
if tkn[0] == 1: #コメント
self.linTemp += "# " + tkn[1]
self.linStat = 9
elif tkn[0] == 200: #ラベル
self.linLabel = tkn[1]
self.linStat = 1
elif tkn[0] == 100: #1st ID
self.linID1 = tkn[1]
self.checkID1()
self.linStat = 3
else:
return False
elif self.linStat == 1:
if tkn[0] == 18: #:
self.linTemp += self.linLabel + ": "
self.linStat = 2
elif tkn[0] == 100: #1st ID
self.linID1 = tkn[1]
self.checkLabelID1()
self.linStat = 3
else:
return False
elif self.linStat == 2:
if tkn[0] == 1: #コメント
self.linTemp += " # " + tkn[1]
self.linStat = 9
elif tkn[0] == 100: #1st ID
self.linID1 = tkn[1]
self.checkID1()
self.linStat = 3
else:
return False
elif self.linStat == 3:
if tkn[0] == 1: #コメント
self.linTemp += " # " + tkn[1]
self.linStat = 9
else:
self.proccessARG(tkn) #引数の解釈
else:
self.writeLine("Error : TOKEN found after valid line end.", True)
self.writeRawToken(tkn)
self.numError += 1
return False
return True
#--------------------------------------------------------------------
[ドキュメント] def proccessARG(self, tkn):
"""check ARG
引数について処理を施す
"""
if self.argOpt[0] == 1:
if self.argOpt[1] == 1: #imm19 branch
self.linTemp += "s." + tkn[1] + " "
elif self.argOpt[1] == 2: #align
if tkn[1] == "2":
self.linTemp += "1 "
elif tkn[1] == "4":
self.linTemp += "2 "
elif tkn[1] == "8":
self.linTemp += "3 "
elif tkn[1] == "16":
self.linTemp += "4 "
elif tkn[1] == "32":
self.linTemp += "5 "
else:
self.linTemp += tkn[1] + " WARNING!-Unknown-alignment "
self.numWarning += 1
self.forceComment = True
self.release = True
elif self.argOpt[1] == 3: #mov_imm16
self.linTemp += "z." + self.convHexFormat(tkn[1]) + " "
elif self.argOpt[1] == 4: #org
adr = self.convHexFormat(tkn[1], True)
if adr == 0x40000000:
self.linTemp += "_start:"
elif (adr > 0x40000000) and (adr < 0x40010000):
self.linTemp += " .org " + hex(adr - 0x40000000)
elif adr == 0x60000000:
self.linTemp += ".data"
elif (adr > 0x60000000) and (adr < 0x60100000):
self.linTemp += " .org " + hex(adr - 0x60000000)
elif self.detectHardwareLocation(tkn[1]):
self.linTemp += " .org SANITIZED: " + tkn[1]
self.forceComment = True
self.sanitized += 1
else:
if self.forceComment:
self.linTemp += " .org " + tkn[1] + " "
else:
self.linTemp += " .org # WARNING!-origin-address-?= " + tkn[1]
self.numWarning += 1
self.forceComment = True
self.release = True
else:
self.linTemp += tkn[1] + " "
self.argOpt = [0, 0]
elif self.argOpt[0] > 1:
self.linTemp += tkn[1] + " "
self.argOpt[0] -= 1
else:
if self.forceComment: #コメントにする場合は何もせずに流す
self.linTemp += tkn[1] + " "
elif self.INCL: #incl疑似命令の処理
if tkn[0]==99 :
self.linTemp += ".include \"" + tkn[1] + ".s\""
else:
self.linTemp += "#.list WARNING!-unexpected-incl-argument-?=" + tkn[1]
self.numWarning += 1
elif self.listArgP: #list疑似命令の処理
if tkn[0]==99 and tkn[1]=="on":
self.linTemp += ".list"
elif tkn[0]==99 and tkn[1]=="off":
self.linTemp += ".nolist"
else:
self.linTemp += "#.list WARNING!-unknown-list-argument-?=" + tkn[1]
self.numWarning += 1
elif self.fifoFlag: #FIFO系命令の引数の処理
num = tryIntParse(tkn[1], 16)
if num < 16:
self.linTemp += tkn[1]
elif tkn[1] in self.equDic:
self.linTemp += str(self.equDic[tkn[1]])
else:
self.forceComment = True
self.release = True
self.linTemp += "# WARNING!-unexpected-fifo-argument-?=" + tkn[1]
self.numWarning += 1
elif tkn[0] == 2: # {
self.linTemp += "( "
elif tkn[0] == 3: # }
self.linTemp += ") "
elif tkn[0] == 19: #location counter
self.linTemp += " WARNING!-location-counter-found $ "
self.numWarning += 1
self.forceComment = True
self.release = True
elif self.macroPending: #マクロ引数チェック、マクロに引数あり
if tkn[0] == 20: # ,
self.linTemp += ", "
else:
self.linTemp += tkn[1] + " "
self.convMacroArgs = True
self.macroArgs.append(tkn[1])
elif self.convMacroArgs: #引数ありマクロの展開中
zFlag = False
tmpArg = tkn[1]
if (len(tmpArg) > 2) and (tmpArg[0:2] == "z."):
tmpArg = tmpArg[2:len(tmpArg)]
zFlag = True
if tmpArg in self.macroArgs:
if zFlag:
self.linTemp += "z.\\" + tmpArg + " "
else:
self.linTemp += "\\" + tmpArg + " "
else:
self.linTemp += self.convHexFormat(tkn[1]) + " "
else:
self.linTemp += self.convHexFormat(tkn[1]) + " "
if self.equFlag: #EQU が99以下の単純な数値なら覚える
num = tryIntParse(tkn[1], 100, 10)
if num < 100:
self.equDic[self.equKEY]=num
self.equFlag = False
return
#--------------------------------------------------------------------
[ドキュメント] def detectHardwareLocation(self, arg):
"""detect Hardware Location
事前定義されているハードウエアロケーションか否かを判定する
"""
if arg.endswith("addr_htu_top"):
return True
elif arg=="htu_buffer":
return True
elif arg.endswith("addr_htu_reg"):
return True
elif arg.endswith("addr_hru_top"):
return True
elif arg=="hru_buffer":
return True
elif arg.endswith("addr_hru_reg"):
return True
else:
return False
#--------------------------------------------------------------------
#--------------------------------------------------------------------
[ドキュメント] def checkID1(self):
"""check ID1
最初の識別子を検査し、変換不要な場合はコメント化する
必要な場合は変換する.
gasに変換する場合に問題が起こるケースもコメント化する
"""
#if self.forceComment: #コメントに落とす場合は何もしない
# self.linTemp += " " + self.linID1 + " "
if self.linID1 == "cpu":
self.linTemp += "# SANITIZED: cpu "
self.sanitized += 1
elif self.linID1 == "hof":
self.linTemp += "# SANITIZED: hof "
self.sanitized += 1
elif self.linID1 == "org":
self.argOpt = [1, 4]
elif (self.linID1 == "dd") or (self.linID1 == "dll"):
self.linTemp += " .long "
elif (self.linID1 == "dw") or (self.linID1 == "dwl"):
self.linTemp += " .short "
elif (self.linID1 == "db") or (self.linID1 == "dfb"):
self.linTemp += " .byte "
elif (self.linID1 == "ds") or (self.linID1 == "dfs"):
self.linTemp += " .zero "
elif self.linID1 == "align":
self.linTemp += " .align "
self.argOpt = [1, 2]
elif self.linID1 == "br_imm19":
self.linTemp += " br.imm19 "
self.argOpt = [1, 1]
elif self.linID1 == "bt_imm19":
self.linTemp += " bt.imm19 "
self.argOpt = [1, 1]
elif self.linID1 == "bf_imm19":
self.linTemp += " bf.imm19 "
self.argOpt = [1, 1]
elif self.linID1 == "bsr_imm19":
self.linTemp += " bsr.imm19 "
self.argOpt = [1, 1]
elif self.linID1 == "mov_imm16":
self.linTemp += " movi.imm16 "
self.argOpt = [3, 3]
elif self.linID1 == "fpush":
self.linTemp += " fpush"
self.fifoFlag = True
elif self.linID1 == "fpop":
self.linTemp += " fpop"
self.fifoFlag = True
elif self.linID1 == "fisync":
self.linTemp += " fisync"
self.fifoFlag = True
elif self.linID1 == "fosync":
self.linTemp += " fosync"
self.fifoFlag = True
elif self.linID1 == "endm":
if self.forceComment:
self.linTemp += "#.endm "
self.forceComment = False
else:
self.linTemp += ".endm "
self.macroArgs = []
self.convFacroArgs = False
elif self.linID1 == "if":
self.linTemp += ".if "
if not self.forceComment:
self.ifNest += 1
elif self.linID1 == "else":
self.linTemp += ".else "
elif self.linID1 == "endi":
self.linTemp += ".endif "
if not self.forceComment:
self.ifNest -= 1
elif self.linID1 == "list":
self.listArgP = True
elif self.linID1 == "incl":
self.INCL = True
else:
self.linTemp += " " + self.linID1 + " "
return
#--------------------------------------------------------------------
[ドキュメント] def checkAlias(self, lbl):
"""check Alias
既知のAliasであればSanitized分類に落とす
既知でなければWarning分類に落とす
いずれもコメント化する
"""
if (lbl == "db") or (lbl == "dw") or (lbl == "dd") or (lbl == "ds"):
self.linTemp += "# SANITIZED: " + self.linLabel + " " + self.linID1 + " "
self.sanitized += 1
else:
self.linTemp += "# WARNING! " + self.linLabel + " " + self.linID1 + " "
self.numWarning += 1
#--------------------------------------------------------------------
[ドキュメント] def checkMacro(self, lbl):
"""check Macro
既知で代替命令の存在するMacroであればSanitized分類に落とす
既知でなければ Macro変換保留扱いとしてマクロ引数へ進む
"""
if (lbl == "push") or (lbl == "pop") or (lbl == "mov_imm16") or (lbl == "align") or \
(lbl == "br_imm19") or (lbl == "bsr_imm19") or (lbl == "bt_imm19") or (lbl == "bf_imm19") or \
(lbl == "blkcopy") or (lbl == "strcomp") or (lbl == "movl"):
self.linTemp += " SANITIZED: " + self.linLabel + " " + self.linID1 + " "
self.forceComment = True
self.sanitized += 1
else:
self.linTemp += ".macro " + self.linLabel + " "
self.macroPending = True
#--------------------------------------------------------------------
[ドキュメント] def checkEqu(self, lbl):
"""check Equ
既知のEquであればSanitized分類に落としてコメント化する
既知でなければ.equ命令に形式変換する
"""
if (lbl.startswith("sizeof_user_stack") or lbl.startswith("sizeof_system_stack")):
self.linTemp += " SANITIZED: .equ " + self.linLabel + ", "
self.forceComment = True
self.release = True
self.sanitized += 1
else:
self.linTemp += " .equ " + self.linLabel + ", "
self.equFlag = True
self.equKEY = self.linLabel
#--------------------------------------------------------------------
[ドキュメント] def checkLabelID1(self):
"""check Label + ID1
Label + ID1形式の特定の組み合わせをコメント化する
必要な場合は変換する.
gasに変換する場合に問題が起こるケースもコメント化する
"""
if self.linID1 == "alias":
self.checkAlias(self.linLabel)
elif self.linID1 == "equ":
self.checkEqu(self.linLabel)
elif self.linID1 == "setl":
self.linTemp += " .set " + self.linLabel + ", "
elif self.linID1 == "macro":
self.checkMacro(self.linLabel)
else:
elf.linTmep += self.linLabel + " " + self.linID1 + " "
return
#--------------------------------------------------------------------
[ドキュメント] def writeRawToken(self, tkn):
"""write Token(RAW) to buffer
生トークンをバッファへ書き込むためのメソッド.
0, EOL
1, COMMENT
2, {
3, }
4, [
5, ]
6, +
7, -
8, *
9, /
10, <
11, >
12, <<
13, >>
14, <=
15, >=
16, ==
17, !=
18, :
19, $
20, ,
21, %
22, &
23, |
99, "string"
100, ID
200, LABEL
999, ERROR-Message
"""
if tkn[0]==0:
self.bufList.append("EOL : " + tkn[1])
elif tkn[0]==1:
self.bufList.append("COMMENT : " + tkn[1])
elif (tkn[0] > 1) and (tkn[0] < 99):
self.bufList.append(tkn[1] + " : " + tkn[1])
elif tkn[0] ==99:
self.bufList.append("STRING : " + tkn[1])
elif tkn[0] ==100:
self.bufList.append("ID : " + tkn[1])
elif tkn[0] ==200:
self.bufList.append("LABEL : " + tkn[1])
else:
self.bufList.append("999 : " + tkn[1])
return False
return True
#--------------------------------------------------------------------
[ドキュメント] def writePredef(self):
"""write Predefined macros/definitions
"""
today = datetime.today()
self.bufList.append("# file converted by " +versionSTR );
self.bufList.append("# " + today.strftime("%Y/%m/%d %H:%M:%S"))
if self.inc:
self.bufList.append("# INC FILE conversion mode.")
else:
self.bufList.append(".altmacro")
self.bufList.append("")
self.bufList.append(".macro push regname")
self.bufList.append(" subi r14, z.4")
self.bufList.append(" st [r14+z.0], \\regname")
self.bufList.append(".endm")
self.bufList.append("")
self.bufList.append(".macro pop regname")
self.bufList.append(" ld \\regname, [r14+z.0]")
self.bufList.append(" addi r14, z.4")
self.bufList.append(".endm")
self.bufList.append("")
self.bufList.append(".macro movl reg, val")
self.bufList.append(".balignw 4, 0xE000")
self.bufList.append(".hword 0xB012")
self.bufList.append(".hword 0x1002")
self.bufList.append(".long \\val")
self.bufList.append(".endm")
self.bufList.append("")
self.bufList.append(" .equ htu_buffer, __addr_htu_top")
self.bufList.append(" .equ hru_buffer, __addr_hru_top")
self.bufList.append("")
self.bufList.append(".text")
self.bufList.append("")
self.bufList.append(".globl _start")
self.bufList.append("")
#=======================================================================
# メインプログラム
def main():
"""main.
メインプログラム
"""
#-----------------------------------------------------------------------
# コマンドラインオプション処理
#
parser = argparse.ArgumentParser(description='asm2s.')
parser.add_argument('--ASM', nargs=1, help='Specify ASM file name.')
parser.add_argument('--S', nargs=1, help='Specify S file name.')
parser.add_argument('-i', dest='inc', help='INC file mode.', action='store_true', default=False)
parser.add_argument('-d', dest='debug', help='Debug mode, print debug information.', action='store_true', default=False)
parser.add_argument('-v', dest='verbose', help='Verbose mode.', action='store_true', default=False)
parser.add_argument('-V', dest='VERSION', help='Show Version, then exit', action='store_true', default=False)
args = parser.parse_args()
#-----------------------------------------------------------------------
# Version 表示
#
print versionSTR
if args.VERSION:
sys.exit(0)
#-----------------------------------------------------------------------
# ファイル名処理
#
if args.ASM is None:
errPrint('ERROR: NO input ASM file!!!')
sys.exit(1)
else:
asmFname = args.ASM[0]
if not os.path.isfile(asmFname):
errPrint('ERROR: ASM file, NOT EXIST.')
sys.exit(1)
if args.S is None:
sFname = "asm_converted.s"
else:
sFname = args.S[0]
#-----------------------------------------------------------------------
# パラメータ処理
#-----------------------------------------------------------------------
# 実処理
#
writer = gasWriter(sFname, args.inc)
writer.verbose = args.verbose
writer.debug = args.debug
#
convertor = asmReader(asmFname, writer, None)
convertor.verbose = args.verbose
convertor.debug = args.debug
if convertor.read():
if not writer.save():
sys.exit(1)
else:
sys.exit(1)
print "# of ERROR: " + str(writer.numError)
print "# of WARNING: " + str(writer.numWarning)
print "# of SANITIZED: " + str(writer.sanitized)
#終了メッセージ
today = datetime.today()
print " "
print today.strftime("FINISH: %Y/%m/%d %H:%M:%S")
#-----------------------------------------------------------------------
# 正常終了
#
sys.exit(0)
#=======================================================================
# メインプログラムの起動
if __name__ == "__main__":
main()