Optimizing L1 cache for embedded systems through grammatical evolution