asm.cc (ragel-7.0.0.9) | : | asm.cc (ragel-7.0.0.10) | ||
---|---|---|---|---|
/* | /* | |||
* Copyright 2014-2015 Adrian Thurston <thurston@complang.org> | * Copyright 2014-2015 Adrian Thurston <thurston@colm.net> | |||
*/ | ||||
/* This file is part of Ragel. | ||||
* | * | |||
* Ragel is free software; you can redistribute it and/or modify | * Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* it under the terms of the GNU General Public License as published by | * of this software and associated documentation files (the "Software"), to | |||
* the Free Software Foundation; either version 2 of the License, or | * deal in the Software without restriction, including without limitation the | |||
* (at your option) any later version. | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |||
* sell copies of the Software, and to permit persons to whom the Software is | ||||
* furnished to do so, subject to the following conditions: | ||||
* | * | |||
* Ragel is distributed in the hope that it will be useful, | * The above copyright notice and this permission notice shall be included in al | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | l | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * copies or substantial portions of the Software. | |||
* GNU General Public License for more details. | ||||
* | * | |||
* You should have received a copy of the GNU General Public License | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* along with Ragel; if not, write to the Free Software | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
* SOFTWARE. | ||||
*/ | */ | |||
#include "ragel.h" | #include "ragel.h" | |||
#include "asm.h" | #include "asm.h" | |||
#include "redfsm.h" | #include "redfsm.h" | |||
#include "gendata.h" | #include "gendata.h" | |||
#include "bstmap.h" | #include "bstmap.h" | |||
#include "ragel.h" | #include "ragel.h" | |||
#include "redfsm.h" | #include "redfsm.h" | |||
#include "bstmap.h" | #include "bstmap.h" | |||
skipping to change at line 1263 | skipping to change at line 1264 | |||
unsigned int AsmCodeGen::EOF_ACTION( RedStateAp *state ) | unsigned int AsmCodeGen::EOF_ACTION( RedStateAp *state ) | |||
{ | { | |||
int act = 0; | int act = 0; | |||
if ( state->eofAction != 0 ) | if ( state->eofAction != 0 ) | |||
act = state->eofAction->location+1; | act = state->eofAction->location+1; | |||
return act; | return act; | |||
} | } | |||
bool AsmCodeGen::useAgainLabel() | bool AsmCodeGen::useAgainLabel() | |||
{ | { | |||
return redFsm->anyRegActionRets() || | return redFsm->anyActionRets() || | |||
redFsm->anyRegActionByValControl() || | redFsm->anyActionByValControl() || | |||
redFsm->anyRegNextStmt(); | redFsm->anyRegNextStmt(); | |||
} | } | |||
void AsmCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) | void AsmCodeGen::GOTO( ostream &ret, int gotoDest, bool inFinish ) | |||
{ | { | |||
if ( inFinish && !noEnd ) { | ||||
out << | ||||
" cmpq " << P() << ", " << PE() << "\n" | ||||
" je " << LABEL( "test_eof", gotoDest ) << "\n | ||||
"; | ||||
} | ||||
ret << | ret << | |||
" jmp " << LABEL( "st", gotoDest ) << "\n"; | " jmp " << LABEL( "st", gotoDest ) << "\n"; | |||
} | } | |||
void AsmCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) | void AsmCodeGen::CALL( ostream &ret, int callDest, int targState, bool inFinish ) | |||
{ | { | |||
if ( red->prePushExpr != 0 ) | if ( red->prePushExpr != 0 ) | |||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | |||
ret << | ret << | |||
" movq " << STACK() << ", %rax\n" | " movq " << STACK() << ", %rax\n" | |||
" movq " << TOP() << ", %rcx\n" | " movq " << TOP() << ", %rcx\n" | |||
" movq $" << targState << ", (%rax, %rcx, 8)\n" | " movq $" << targState << ", (%rax, %rcx, 8)\n" | |||
" addq $1, %rcx\n" | " addq $1, %rcx\n" | |||
" movq %rcx, " << TOP() << "\n" | " movq %rcx, " << TOP() << "\n" | |||
; | ||||
if ( inFinish && !noEnd ) { | ||||
out << | ||||
" cmpq " << P() << ", " << PE() << "\n" | ||||
" je " << LABEL( "test_eof", callDest ) << "\n | ||||
"; | ||||
} | ||||
ret << | ||||
" jmp " << LABEL( "st", callDest ) << "\n"; | " jmp " << LABEL( "st", callDest ) << "\n"; | |||
; | ; | |||
} | } | |||
void AsmCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) | void AsmCodeGen::CALL_EXPR( ostream &ret, GenInlineItem *ilItem, int targState, bool inFinish ) | |||
{ | { | |||
if ( red->prePushExpr != 0 ) | if ( red->prePushExpr != 0 ) | |||
INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | INLINE_LIST( ret, red->prePushExpr->inlineList, 0, false, false ) ; | |||
ret << | ret << | |||
skipping to change at line 1306 | skipping to change at line 1322 | |||
" movq "; | " movq "; | |||
INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | |||
ret << ", %rdx\n" | ret << ", %rdx\n" | |||
"\n" | "\n" | |||
" movq " << STACK() << ", %rax\n" | " movq " << STACK() << ", %rax\n" | |||
" movq " << TOP() << ", %rcx\n" | " movq " << TOP() << ", %rcx\n" | |||
" movq $" << targState << ", (%rax, %rcx, 8)\n" | " movq $" << targState << ", (%rax, %rcx, 8)\n" | |||
" addq $1, %rcx\n" | " addq $1, %rcx\n" | |||
" movq %rcx, " << TOP() << "\n" | " movq %rcx, " << TOP() << "\n" | |||
" movq %rdx, " << vCS() << "\n" | " movq %rdx, " << vCS() << "\n" | |||
; | ||||
if ( inFinish && !noEnd ) { | ||||
out << | ||||
" cmpq " << P() << ", " << PE() << "\n" | ||||
" je " << LABEL( "test_eof" ) << "\n"; | ||||
} | ||||
ret << | ||||
" jmp " << LABEL( "again" ) << "\n"; | " jmp " << LABEL( "again" ) << "\n"; | |||
} | } | |||
void AsmCodeGen::RET( ostream &ret, bool inFinish ) | void AsmCodeGen::RET( ostream &ret, bool inFinish ) | |||
{ | { | |||
ret << | ret << | |||
" movq " << STACK() << ", %rax\n" | " movq " << STACK() << ", %rax\n" | |||
" movq " << TOP() << ", %rcx\n" | " movq " << TOP() << ", %rcx\n" | |||
" subq $1, %rcx\n" | " subq $1, %rcx\n" | |||
" movq (%rax, %rcx, 8), %rax\n" | " movq (%rax, %rcx, 8), %rax\n" | |||
" movq %rax, " << vCS() << "\n" | " movq %rax, " << vCS() << "\n" | |||
" movq %rcx, " << TOP() << "\n"; | " movq %rcx, " << TOP() << "\n"; | |||
if ( red->postPopExpr != 0 ) | if ( red->postPopExpr != 0 ) | |||
INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) ; | INLINE_LIST( ret, red->postPopExpr->inlineList, 0, false, false ) ; | |||
if ( inFinish && !noEnd ) { | ||||
out << | ||||
" cmpq " << P() << ", " << PE() << "\n" | ||||
" je " << LABEL( "test_eof" ) << "\n"; | ||||
} | ||||
ret << | ret << | |||
" jmp " << LABEL("again") << "\n"; | " jmp " << LABEL("again") << "\n"; | |||
} | } | |||
void AsmCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) | void AsmCodeGen::GOTO_EXPR( ostream &ret, GenInlineItem *ilItem, bool inFinish ) | |||
{ | { | |||
ret << " movq "; | ret << " movq "; | |||
INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | INLINE_LIST( ret, ilItem->children, 0, inFinish, false ); | |||
ret << ", " << vCS() << "\n"; | ret << ", " << vCS() << "\n"; | |||
if ( inFinish && !noEnd ) { | ||||
out << | ||||
" cmpq " << P() << ", " << PE() << "\n" | ||||
" je " << LABEL( "test_eof" ) << "\n"; | ||||
} | ||||
ret << | ret << | |||
" jmp " << LABEL("again") << "\n"; | " jmp " << LABEL("again") << "\n"; | |||
} | } | |||
void AsmCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) | void AsmCodeGen::NEXT( ostream &ret, int nextDest, bool inFinish ) | |||
{ | { | |||
ret << | ret << | |||
" movq $" << nextDest << ", " << vCS() << "\n"; | " movq $" << nextDest << ", " << vCS() << "\n"; | |||
} | } | |||
skipping to change at line 1810 | skipping to change at line 1847 | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | |||
st->labelNeeded = false; | st->labelNeeded = false; | |||
for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); tra ns++ ) { | for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); tra ns++ ) { | |||
if ( trans->condSpace == 0 ) | if ( trans->condSpace == 0 ) | |||
setLabelsNeeded( &trans->p ); | setLabelsNeeded( &trans->p ); | |||
} | } | |||
for ( CondApSet::Iter cond = redFsm->condSet; cond.lte(); cond++ ) | for ( CondApSet::Iter cond = redFsm->condSet; cond.lte(); cond++ ) | |||
setLabelsNeeded( &cond->p ); | setLabelsNeeded( &cond->p ); | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | ||||
{ | ||||
if ( st->eofAction != 0 ) { | ||||
for ( GenActionTable::Iter item = st->eofAction-> | ||||
key; item.lte(); item++ ) | ||||
setLabelsNeeded( item->value->inlineList | ||||
); | ||||
} | ||||
} | ||||
} | } | |||
if ( !noEnd ) { | if ( !noEnd ) { | |||
for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) | |||
st->outNeeded = st->labelNeeded; | st->outNeeded = st->labelNeeded; | |||
} | } | |||
} | } | |||
void AsmCodeGen::writeData() | void AsmCodeGen::writeData() | |||
{ | { | |||
End of changes. 11 change blocks. | ||||
17 lines changed or deleted | 67 lines changed or added |